unsakini 0.0.3 → 0.0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -7
- data/angular/README.md +31 -1
- data/angular/dist/inline.map +1 -1
- data/angular/dist/main.bundle.js +64 -110
- data/angular/dist/main.map +1 -1
- data/angular/dist/styles.map +1 -1
- data/angular/package.json +2 -1
- data/app/controllers/api/comments_controller.rb +1 -1
- data/app/controllers/api/posts_controller.rb +1 -1
- data/lib/unsakini/version.rb +1 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/app/inline.map +1 -1
- data/spec/dummy/public/app/main.bundle.js +64 -110
- data/spec/dummy/public/app/main.map +1 -1
- data/spec/dummy/public/app/styles.map +1 -1
- data/spec/requests/api/boards/api_boards_pagination_spec.rb +16 -0
- data/spec/requests/api/comments/api_comments_pagination_spec.rb +31 -0
- data/spec/requests/api/comments/api_comments_private_board_spec.rb +197 -0
- data/spec/requests/api/comments/{api_comments_spec.rb → api_comments_shared_board_spec.rb} +0 -180
- data/spec/requests/api/posts/api_posts_pagination_spec.rb +34 -0
- data/spec/requests/api/posts/api_posts_private_board_spec.rb +136 -0
- data/spec/requests/api/posts/{api_posts_spec.rb → api_posts_shared_board_spec.rb} +0 -116
- data/spec/support/scenario_helper.rb +34 -2
- metadata +13 -6
- data/angular/LICENSE +0 -21
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["webpack:////home/adones/Projects/UNSAKINI/unsakini-ng2/src/styles.css?46c6","webpack:////home/adones/Projects/UNSAKINI/unsakini-ng2/src/styles.css","webpack:////home/adones/Projects/UNSAKINI/unsakini-ng2/~/css-loader/lib/css-base.js","webpack:////home/adones/Projects/UNSAKINI/unsakini-ng2/~/style-loader/addStyles.js"],"names":[],"mappings":";;;;;AAAA;;AAEA;AACA;AACA;AACA;AACA,iDAAgF;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,gCAAgC,UAAU,EAAE;AAC5C,C;;;;;;;ACpBA;AACA;;;AAGA;AACA;;AAEA;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA,wCAAwC,gBAAgB;AACxD,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACjDA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sBAAsB;AACtC;AACA;AACA,kBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,iBAAiB,2BAA2B;AAC5C;AACA;AACA,QAAQ,uBAAuB;AAC/B;AACA;AACA,GAAG;AACH;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA,EAAE;AACF;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;;AAEA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uDAAuD;AACvD;;AAEA,6BAA6B,mBAAmB;;AAEhD;;AAEA;;AAEA;AACA;AACA","file":"styles.bundle.js","sourcesContent":["// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../node_modules/css-loader/index.js?sourcemap!./../node_modules/postcss-loader/index.js!./styles.css\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../node_modules/css-loader/index.js?sourcemap!./../node_modules/postcss-loader/index.js!./styles.css\", function() {\n\t\t\tvar newContent = require(\"!!./../node_modules/css-loader/index.js?sourcemap!./../node_modules/postcss-loader/index.js!./styles.css\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini-ng2/src/styles.css\n// module id = 379\n// module chunks = 1","exports = module.exports = require(\"./../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/* You can add global styles to this file, and also import other style files */\\n\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini-ng2/~/css-loader?sourcemap!/home/adones/Projects/UNSAKINI/unsakini-ng2/~/postcss-loader!/home/adones/Projects/UNSAKINI/unsakini-ng2/src/styles.css\n// module id = 652\n// module chunks = 1","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini-ng2/~/css-loader/lib/css-base.js\n// module id = 653\n// module chunks = 1","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\nvar stylesInDom = {},\r\n\tmemoize = function(fn) {\r\n\t\tvar memo;\r\n\t\treturn function () {\r\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\r\n\t\t\treturn memo;\r\n\t\t};\r\n\t},\r\n\tisOldIE = memoize(function() {\r\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\r\n\t}),\r\n\tgetHeadElement = memoize(function () {\r\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\r\n\t}),\r\n\tsingletonElement = null,\r\n\tsingletonCounter = 0,\r\n\tstyleElementsInsertedAtTop = [];\r\n\r\nmodule.exports = function(list, options) {\r\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\r\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\r\n\t}\r\n\r\n\toptions = options || {};\r\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\r\n\t// tags it will allow on a page\r\n\tif (typeof options.singleton === \"undefined\") options.singleton = isOldIE();\r\n\r\n\t// By default, add <style> tags to the bottom of <head>.\r\n\tif (typeof options.insertAt === \"undefined\") options.insertAt = \"bottom\";\r\n\r\n\tvar styles = listToStyles(list);\r\n\taddStylesToDom(styles, options);\r\n\r\n\treturn function update(newList) {\r\n\t\tvar mayRemove = [];\r\n\t\tfor(var i = 0; i < styles.length; i++) {\r\n\t\t\tvar item = styles[i];\r\n\t\t\tvar domStyle = stylesInDom[item.id];\r\n\t\t\tdomStyle.refs--;\r\n\t\t\tmayRemove.push(domStyle);\r\n\t\t}\r\n\t\tif(newList) {\r\n\t\t\tvar newStyles = listToStyles(newList);\r\n\t\t\taddStylesToDom(newStyles, options);\r\n\t\t}\r\n\t\tfor(var i = 0; i < mayRemove.length; i++) {\r\n\t\t\tvar domStyle = mayRemove[i];\r\n\t\t\tif(domStyle.refs === 0) {\r\n\t\t\t\tfor(var j = 0; j < domStyle.parts.length; j++)\r\n\t\t\t\t\tdomStyle.parts[j]();\r\n\t\t\t\tdelete stylesInDom[domStyle.id];\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n}\r\n\r\nfunction addStylesToDom(styles, options) {\r\n\tfor(var i = 0; i < styles.length; i++) {\r\n\t\tvar item = styles[i];\r\n\t\tvar domStyle = stylesInDom[item.id];\r\n\t\tif(domStyle) {\r\n\t\t\tdomStyle.refs++;\r\n\t\t\tfor(var j = 0; j < domStyle.parts.length; j++) {\r\n\t\t\t\tdomStyle.parts[j](item.parts[j]);\r\n\t\t\t}\r\n\t\t\tfor(; j < item.parts.length; j++) {\r\n\t\t\t\tdomStyle.parts.push(addStyle(item.parts[j], options));\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tvar parts = [];\r\n\t\t\tfor(var j = 0; j < item.parts.length; j++) {\r\n\t\t\t\tparts.push(addStyle(item.parts[j], options));\r\n\t\t\t}\r\n\t\t\tstylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction listToStyles(list) {\r\n\tvar styles = [];\r\n\tvar newStyles = {};\r\n\tfor(var i = 0; i < list.length; i++) {\r\n\t\tvar item = list[i];\r\n\t\tvar id = item[0];\r\n\t\tvar css = item[1];\r\n\t\tvar media = item[2];\r\n\t\tvar sourceMap = item[3];\r\n\t\tvar part = {css: css, media: media, sourceMap: sourceMap};\r\n\t\tif(!newStyles[id])\r\n\t\t\tstyles.push(newStyles[id] = {id: id, parts: [part]});\r\n\t\telse\r\n\t\t\tnewStyles[id].parts.push(part);\r\n\t}\r\n\treturn styles;\r\n}\r\n\r\nfunction insertStyleElement(options, styleElement) {\r\n\tvar head = getHeadElement();\r\n\tvar lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];\r\n\tif (options.insertAt === \"top\") {\r\n\t\tif(!lastStyleElementInsertedAtTop) {\r\n\t\t\thead.insertBefore(styleElement, head.firstChild);\r\n\t\t} else if(lastStyleElementInsertedAtTop.nextSibling) {\r\n\t\t\thead.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);\r\n\t\t} else {\r\n\t\t\thead.appendChild(styleElement);\r\n\t\t}\r\n\t\tstyleElementsInsertedAtTop.push(styleElement);\r\n\t} else if (options.insertAt === \"bottom\") {\r\n\t\thead.appendChild(styleElement);\r\n\t} else {\r\n\t\tthrow new Error(\"Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.\");\r\n\t}\r\n}\r\n\r\nfunction removeStyleElement(styleElement) {\r\n\tstyleElement.parentNode.removeChild(styleElement);\r\n\tvar idx = styleElementsInsertedAtTop.indexOf(styleElement);\r\n\tif(idx >= 0) {\r\n\t\tstyleElementsInsertedAtTop.splice(idx, 1);\r\n\t}\r\n}\r\n\r\nfunction createStyleElement(options) {\r\n\tvar styleElement = document.createElement(\"style\");\r\n\tstyleElement.type = \"text/css\";\r\n\tinsertStyleElement(options, styleElement);\r\n\treturn styleElement;\r\n}\r\n\r\nfunction createLinkElement(options) {\r\n\tvar linkElement = document.createElement(\"link\");\r\n\tlinkElement.rel = \"stylesheet\";\r\n\tinsertStyleElement(options, linkElement);\r\n\treturn linkElement;\r\n}\r\n\r\nfunction addStyle(obj, options) {\r\n\tvar styleElement, update, remove;\r\n\r\n\tif (options.singleton) {\r\n\t\tvar styleIndex = singletonCounter++;\r\n\t\tstyleElement = singletonElement || (singletonElement = createStyleElement(options));\r\n\t\tupdate = applyToSingletonTag.bind(null, styleElement, styleIndex, false);\r\n\t\tremove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);\r\n\t} else if(obj.sourceMap &&\r\n\t\ttypeof URL === \"function\" &&\r\n\t\ttypeof URL.createObjectURL === \"function\" &&\r\n\t\ttypeof URL.revokeObjectURL === \"function\" &&\r\n\t\ttypeof Blob === \"function\" &&\r\n\t\ttypeof btoa === \"function\") {\r\n\t\tstyleElement = createLinkElement(options);\r\n\t\tupdate = updateLink.bind(null, styleElement);\r\n\t\tremove = function() {\r\n\t\t\tremoveStyleElement(styleElement);\r\n\t\t\tif(styleElement.href)\r\n\t\t\t\tURL.revokeObjectURL(styleElement.href);\r\n\t\t};\r\n\t} else {\r\n\t\tstyleElement = createStyleElement(options);\r\n\t\tupdate = applyToTag.bind(null, styleElement);\r\n\t\tremove = function() {\r\n\t\t\tremoveStyleElement(styleElement);\r\n\t\t};\r\n\t}\r\n\r\n\tupdate(obj);\r\n\r\n\treturn function updateStyle(newObj) {\r\n\t\tif(newObj) {\r\n\t\t\tif(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)\r\n\t\t\t\treturn;\r\n\t\t\tupdate(obj = newObj);\r\n\t\t} else {\r\n\t\t\tremove();\r\n\t\t}\r\n\t};\r\n}\r\n\r\nvar replaceText = (function () {\r\n\tvar textStore = [];\r\n\r\n\treturn function (index, replacement) {\r\n\t\ttextStore[index] = replacement;\r\n\t\treturn textStore.filter(Boolean).join('\\n');\r\n\t};\r\n})();\r\n\r\nfunction applyToSingletonTag(styleElement, index, remove, obj) {\r\n\tvar css = remove ? \"\" : obj.css;\r\n\r\n\tif (styleElement.styleSheet) {\r\n\t\tstyleElement.styleSheet.cssText = replaceText(index, css);\r\n\t} else {\r\n\t\tvar cssNode = document.createTextNode(css);\r\n\t\tvar childNodes = styleElement.childNodes;\r\n\t\tif (childNodes[index]) styleElement.removeChild(childNodes[index]);\r\n\t\tif (childNodes.length) {\r\n\t\t\tstyleElement.insertBefore(cssNode, childNodes[index]);\r\n\t\t} else {\r\n\t\t\tstyleElement.appendChild(cssNode);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction applyToTag(styleElement, obj) {\r\n\tvar css = obj.css;\r\n\tvar media = obj.media;\r\n\r\n\tif(media) {\r\n\t\tstyleElement.setAttribute(\"media\", media)\r\n\t}\r\n\r\n\tif(styleElement.styleSheet) {\r\n\t\tstyleElement.styleSheet.cssText = css;\r\n\t} else {\r\n\t\twhile(styleElement.firstChild) {\r\n\t\t\tstyleElement.removeChild(styleElement.firstChild);\r\n\t\t}\r\n\t\tstyleElement.appendChild(document.createTextNode(css));\r\n\t}\r\n}\r\n\r\nfunction updateLink(linkElement, obj) {\r\n\tvar css = obj.css;\r\n\tvar sourceMap = obj.sourceMap;\r\n\r\n\tif(sourceMap) {\r\n\t\t// http://stackoverflow.com/a/26603875\r\n\t\tcss += \"\\n/*# sourceMappingURL=data:application/json;base64,\" + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + \" */\";\r\n\t}\r\n\r\n\tvar blob = new Blob([css], { type: \"text/css\" });\r\n\r\n\tvar oldSrc = linkElement.href;\r\n\r\n\tlinkElement.href = URL.createObjectURL(blob);\r\n\r\n\tif(oldSrc)\r\n\t\tURL.revokeObjectURL(oldSrc);\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini-ng2/~/style-loader/addStyles.js\n// module id = 695\n// module chunks = 1"],"sourceRoot":""}
|
1
|
+
{"version":3,"sources":["webpack:////home/adones/Projects/UNSAKINI/unsakini/angular/src/styles.css?95a1","webpack:////home/adones/Projects/UNSAKINI/unsakini/angular/src/styles.css","webpack:////home/adones/Projects/UNSAKINI/unsakini/angular/~/css-loader/lib/css-base.js","webpack:////home/adones/Projects/UNSAKINI/unsakini/angular/~/style-loader/addStyles.js"],"names":[],"mappings":";;;;;AAAA;;AAEA;AACA;AACA;AACA;AACA,iDAAgF;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,gCAAgC,UAAU,EAAE;AAC5C,C;;;;;;;ACpBA;AACA;;;AAGA;AACA;;AAEA;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA,wCAAwC,gBAAgB;AACxD,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACjDA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sBAAsB;AACtC;AACA;AACA,kBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,iBAAiB,2BAA2B;AAC5C;AACA;AACA,QAAQ,uBAAuB;AAC/B;AACA;AACA,GAAG;AACH;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA,EAAE;AACF;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;;AAEA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uDAAuD;AACvD;;AAEA,6BAA6B,mBAAmB;;AAEhD;;AAEA;;AAEA;AACA;AACA","file":"styles.bundle.js","sourcesContent":["// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!./../node_modules/css-loader/index.js?sourcemap!./../node_modules/postcss-loader/index.js!./styles.css\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../node_modules/style-loader/addStyles.js\")(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../node_modules/css-loader/index.js?sourcemap!./../node_modules/postcss-loader/index.js!./styles.css\", function() {\n\t\t\tvar newContent = require(\"!!./../node_modules/css-loader/index.js?sourcemap!./../node_modules/postcss-loader/index.js!./styles.css\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini/angular/src/styles.css\n// module id = 379\n// module chunks = 1","exports = module.exports = require(\"./../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/* You can add global styles to this file, and also import other style files */\\n\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini/angular/~/css-loader?sourcemap!/home/adones/Projects/UNSAKINI/unsakini/angular/~/postcss-loader!/home/adones/Projects/UNSAKINI/unsakini/angular/src/styles.css\n// module id = 652\n// module chunks = 1","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini/angular/~/css-loader/lib/css-base.js\n// module id = 653\n// module chunks = 1","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\nvar stylesInDom = {},\r\n\tmemoize = function(fn) {\r\n\t\tvar memo;\r\n\t\treturn function () {\r\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\r\n\t\t\treturn memo;\r\n\t\t};\r\n\t},\r\n\tisOldIE = memoize(function() {\r\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\r\n\t}),\r\n\tgetHeadElement = memoize(function () {\r\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\r\n\t}),\r\n\tsingletonElement = null,\r\n\tsingletonCounter = 0,\r\n\tstyleElementsInsertedAtTop = [];\r\n\r\nmodule.exports = function(list, options) {\r\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\r\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\r\n\t}\r\n\r\n\toptions = options || {};\r\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\r\n\t// tags it will allow on a page\r\n\tif (typeof options.singleton === \"undefined\") options.singleton = isOldIE();\r\n\r\n\t// By default, add <style> tags to the bottom of <head>.\r\n\tif (typeof options.insertAt === \"undefined\") options.insertAt = \"bottom\";\r\n\r\n\tvar styles = listToStyles(list);\r\n\taddStylesToDom(styles, options);\r\n\r\n\treturn function update(newList) {\r\n\t\tvar mayRemove = [];\r\n\t\tfor(var i = 0; i < styles.length; i++) {\r\n\t\t\tvar item = styles[i];\r\n\t\t\tvar domStyle = stylesInDom[item.id];\r\n\t\t\tdomStyle.refs--;\r\n\t\t\tmayRemove.push(domStyle);\r\n\t\t}\r\n\t\tif(newList) {\r\n\t\t\tvar newStyles = listToStyles(newList);\r\n\t\t\taddStylesToDom(newStyles, options);\r\n\t\t}\r\n\t\tfor(var i = 0; i < mayRemove.length; i++) {\r\n\t\t\tvar domStyle = mayRemove[i];\r\n\t\t\tif(domStyle.refs === 0) {\r\n\t\t\t\tfor(var j = 0; j < domStyle.parts.length; j++)\r\n\t\t\t\t\tdomStyle.parts[j]();\r\n\t\t\t\tdelete stylesInDom[domStyle.id];\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n}\r\n\r\nfunction addStylesToDom(styles, options) {\r\n\tfor(var i = 0; i < styles.length; i++) {\r\n\t\tvar item = styles[i];\r\n\t\tvar domStyle = stylesInDom[item.id];\r\n\t\tif(domStyle) {\r\n\t\t\tdomStyle.refs++;\r\n\t\t\tfor(var j = 0; j < domStyle.parts.length; j++) {\r\n\t\t\t\tdomStyle.parts[j](item.parts[j]);\r\n\t\t\t}\r\n\t\t\tfor(; j < item.parts.length; j++) {\r\n\t\t\t\tdomStyle.parts.push(addStyle(item.parts[j], options));\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tvar parts = [];\r\n\t\t\tfor(var j = 0; j < item.parts.length; j++) {\r\n\t\t\t\tparts.push(addStyle(item.parts[j], options));\r\n\t\t\t}\r\n\t\t\tstylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction listToStyles(list) {\r\n\tvar styles = [];\r\n\tvar newStyles = {};\r\n\tfor(var i = 0; i < list.length; i++) {\r\n\t\tvar item = list[i];\r\n\t\tvar id = item[0];\r\n\t\tvar css = item[1];\r\n\t\tvar media = item[2];\r\n\t\tvar sourceMap = item[3];\r\n\t\tvar part = {css: css, media: media, sourceMap: sourceMap};\r\n\t\tif(!newStyles[id])\r\n\t\t\tstyles.push(newStyles[id] = {id: id, parts: [part]});\r\n\t\telse\r\n\t\t\tnewStyles[id].parts.push(part);\r\n\t}\r\n\treturn styles;\r\n}\r\n\r\nfunction insertStyleElement(options, styleElement) {\r\n\tvar head = getHeadElement();\r\n\tvar lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];\r\n\tif (options.insertAt === \"top\") {\r\n\t\tif(!lastStyleElementInsertedAtTop) {\r\n\t\t\thead.insertBefore(styleElement, head.firstChild);\r\n\t\t} else if(lastStyleElementInsertedAtTop.nextSibling) {\r\n\t\t\thead.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);\r\n\t\t} else {\r\n\t\t\thead.appendChild(styleElement);\r\n\t\t}\r\n\t\tstyleElementsInsertedAtTop.push(styleElement);\r\n\t} else if (options.insertAt === \"bottom\") {\r\n\t\thead.appendChild(styleElement);\r\n\t} else {\r\n\t\tthrow new Error(\"Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.\");\r\n\t}\r\n}\r\n\r\nfunction removeStyleElement(styleElement) {\r\n\tstyleElement.parentNode.removeChild(styleElement);\r\n\tvar idx = styleElementsInsertedAtTop.indexOf(styleElement);\r\n\tif(idx >= 0) {\r\n\t\tstyleElementsInsertedAtTop.splice(idx, 1);\r\n\t}\r\n}\r\n\r\nfunction createStyleElement(options) {\r\n\tvar styleElement = document.createElement(\"style\");\r\n\tstyleElement.type = \"text/css\";\r\n\tinsertStyleElement(options, styleElement);\r\n\treturn styleElement;\r\n}\r\n\r\nfunction createLinkElement(options) {\r\n\tvar linkElement = document.createElement(\"link\");\r\n\tlinkElement.rel = \"stylesheet\";\r\n\tinsertStyleElement(options, linkElement);\r\n\treturn linkElement;\r\n}\r\n\r\nfunction addStyle(obj, options) {\r\n\tvar styleElement, update, remove;\r\n\r\n\tif (options.singleton) {\r\n\t\tvar styleIndex = singletonCounter++;\r\n\t\tstyleElement = singletonElement || (singletonElement = createStyleElement(options));\r\n\t\tupdate = applyToSingletonTag.bind(null, styleElement, styleIndex, false);\r\n\t\tremove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);\r\n\t} else if(obj.sourceMap &&\r\n\t\ttypeof URL === \"function\" &&\r\n\t\ttypeof URL.createObjectURL === \"function\" &&\r\n\t\ttypeof URL.revokeObjectURL === \"function\" &&\r\n\t\ttypeof Blob === \"function\" &&\r\n\t\ttypeof btoa === \"function\") {\r\n\t\tstyleElement = createLinkElement(options);\r\n\t\tupdate = updateLink.bind(null, styleElement);\r\n\t\tremove = function() {\r\n\t\t\tremoveStyleElement(styleElement);\r\n\t\t\tif(styleElement.href)\r\n\t\t\t\tURL.revokeObjectURL(styleElement.href);\r\n\t\t};\r\n\t} else {\r\n\t\tstyleElement = createStyleElement(options);\r\n\t\tupdate = applyToTag.bind(null, styleElement);\r\n\t\tremove = function() {\r\n\t\t\tremoveStyleElement(styleElement);\r\n\t\t};\r\n\t}\r\n\r\n\tupdate(obj);\r\n\r\n\treturn function updateStyle(newObj) {\r\n\t\tif(newObj) {\r\n\t\t\tif(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)\r\n\t\t\t\treturn;\r\n\t\t\tupdate(obj = newObj);\r\n\t\t} else {\r\n\t\t\tremove();\r\n\t\t}\r\n\t};\r\n}\r\n\r\nvar replaceText = (function () {\r\n\tvar textStore = [];\r\n\r\n\treturn function (index, replacement) {\r\n\t\ttextStore[index] = replacement;\r\n\t\treturn textStore.filter(Boolean).join('\\n');\r\n\t};\r\n})();\r\n\r\nfunction applyToSingletonTag(styleElement, index, remove, obj) {\r\n\tvar css = remove ? \"\" : obj.css;\r\n\r\n\tif (styleElement.styleSheet) {\r\n\t\tstyleElement.styleSheet.cssText = replaceText(index, css);\r\n\t} else {\r\n\t\tvar cssNode = document.createTextNode(css);\r\n\t\tvar childNodes = styleElement.childNodes;\r\n\t\tif (childNodes[index]) styleElement.removeChild(childNodes[index]);\r\n\t\tif (childNodes.length) {\r\n\t\t\tstyleElement.insertBefore(cssNode, childNodes[index]);\r\n\t\t} else {\r\n\t\t\tstyleElement.appendChild(cssNode);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction applyToTag(styleElement, obj) {\r\n\tvar css = obj.css;\r\n\tvar media = obj.media;\r\n\r\n\tif(media) {\r\n\t\tstyleElement.setAttribute(\"media\", media)\r\n\t}\r\n\r\n\tif(styleElement.styleSheet) {\r\n\t\tstyleElement.styleSheet.cssText = css;\r\n\t} else {\r\n\t\twhile(styleElement.firstChild) {\r\n\t\t\tstyleElement.removeChild(styleElement.firstChild);\r\n\t\t}\r\n\t\tstyleElement.appendChild(document.createTextNode(css));\r\n\t}\r\n}\r\n\r\nfunction updateLink(linkElement, obj) {\r\n\tvar css = obj.css;\r\n\tvar sourceMap = obj.sourceMap;\r\n\r\n\tif(sourceMap) {\r\n\t\t// http://stackoverflow.com/a/26603875\r\n\t\tcss += \"\\n/*# sourceMappingURL=data:application/json;base64,\" + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + \" */\";\r\n\t}\r\n\r\n\tvar blob = new Blob([css], { type: \"text/css\" });\r\n\r\n\tvar oldSrc = linkElement.href;\r\n\r\n\tlinkElement.href = URL.createObjectURL(blob);\r\n\r\n\tif(oldSrc)\r\n\t\tURL.revokeObjectURL(oldSrc);\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// /home/adones/Projects/UNSAKINI/unsakini/angular/~/style-loader/addStyles.js\n// module id = 695\n// module chunks = 1"],"sourceRoot":""}
|
@@ -25,6 +25,14 @@ RSpec.describe "Api::Boards", type: :request do
|
|
25
25
|
expect(get_header("Total").to_i).to eq @num_boards
|
26
26
|
end
|
27
27
|
|
28
|
+
it "returns current user's boards last page" do
|
29
|
+
get api_boards_path, params: {page: 2}, headers: auth_headers(@user)
|
30
|
+
expect(response).to have_http_status(:ok)
|
31
|
+
expect(body_to_json.count).to eq @num_boards - num_per_page
|
32
|
+
expect(body_to_json('0')).to match_json_schema(:board)
|
33
|
+
expect(get_header("Total").to_i).to eq @num_boards
|
34
|
+
end
|
35
|
+
|
28
36
|
end
|
29
37
|
|
30
38
|
end
|
@@ -41,6 +49,14 @@ RSpec.describe "Api::Boards", type: :request do
|
|
41
49
|
expect(get_header("Total").to_i).to eq @num_my_shared_boards
|
42
50
|
end
|
43
51
|
|
52
|
+
it "returns current user's boards last page" do
|
53
|
+
get api_boards_path, params: {page: 2, admin: true, shared: true}, headers: auth_headers(@user)
|
54
|
+
expect(response).to have_http_status(:ok)
|
55
|
+
expect(body_to_json.count).to eq @num_my_shared_boards - num_per_page
|
56
|
+
expect(body_to_json('0')).to match_json_schema(:board)
|
57
|
+
expect(get_header("Total").to_i).to eq @num_my_shared_boards
|
58
|
+
end
|
59
|
+
|
44
60
|
end
|
45
61
|
|
46
62
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Api::Board::Post::Comments", type: :request do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
post_has_many_comments_scenario
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:num_per_page) {
|
10
|
+
20
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "Pagination" do
|
14
|
+
|
15
|
+
it "returns first 20 comments" do
|
16
|
+
get api_board_post_comments_path(@board, @post), headers: auth_headers(@user), params: {page: 1}
|
17
|
+
expect(body_to_json.count).to eq num_per_page
|
18
|
+
expect(body_to_json('0')).to match_json_schema(:comment)
|
19
|
+
expect(get_header("Total").to_i).to eq @num_comments
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns last page" do
|
23
|
+
get api_board_post_comments_path(@board, @post), headers: auth_headers(@user), params: {page: 2}
|
24
|
+
expect(body_to_json('0')).to match_json_schema(:comment)
|
25
|
+
expect(get_header("Total").to_i).to eq @num_comments
|
26
|
+
expect(body_to_json.count).to eq @num_comments - num_per_page
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Api::Board::Post::Comments", type: :request do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
user_has_shared_board_with_posts_scenario
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:valid_attributes) {
|
10
|
+
{content: Faker::Hacker.say_something_smart}
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:invalid_attributes) {
|
14
|
+
{content: nil}
|
15
|
+
}
|
16
|
+
|
17
|
+
context "Private board" do
|
18
|
+
|
19
|
+
context "Comments on my post" do
|
20
|
+
|
21
|
+
it "returns http unauthorized" do
|
22
|
+
get api_board_post_comments_path(@board, @post)
|
23
|
+
expect(response).to have_http_status(:unauthorized)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns http unauthorized" do
|
27
|
+
put api_board_post_comment_path(@board, @post, @comment), params: valid_attributes, as: :json
|
28
|
+
expect(response).to have_http_status(:unauthorized)
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
describe "Get all comments on my post" do
|
33
|
+
describe "As a post owner" do
|
34
|
+
it "returns all comments" do
|
35
|
+
get api_board_post_comments_path(@board, @post), headers: auth_headers(@user)
|
36
|
+
expect(response).to have_http_status(:ok)
|
37
|
+
expect(body_to_json('0')).to match_json_schema(:comment)
|
38
|
+
expect(body_to_json.count).to eq @post.comments.count
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "As another user" do
|
43
|
+
it "returns http forbidden" do
|
44
|
+
get api_board_post_comments_path(@board, @post), headers: auth_headers(@user_2)
|
45
|
+
expect(response).to have_http_status(:forbidden)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns http forbidden" do
|
49
|
+
get api_board_post_comments_path(@shared_board, @post), headers: auth_headers(@user_2)
|
50
|
+
expect(response).to have_http_status(:forbidden)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "Creating comment to my post" do
|
57
|
+
|
58
|
+
describe "As post owner" do
|
59
|
+
|
60
|
+
it "returns http unauthorized" do
|
61
|
+
post api_board_post_comments_path(@board, @post), as: :json, params: valid_attributes
|
62
|
+
expect(response).to have_http_status(:unauthorized)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns http unprocessable_entity" do
|
66
|
+
post(
|
67
|
+
api_board_post_comments_path(@board, @post),
|
68
|
+
headers: auth_headers(@user),
|
69
|
+
params: invalid_attributes,
|
70
|
+
as: :json
|
71
|
+
)
|
72
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
73
|
+
#todo: assert errors
|
74
|
+
end
|
75
|
+
|
76
|
+
it "creates a new comment" do
|
77
|
+
comment_count = @post.comments.count
|
78
|
+
post(
|
79
|
+
api_board_post_comments_path(@board, @post),
|
80
|
+
headers: auth_headers(@user),
|
81
|
+
params: valid_attributes,
|
82
|
+
as: :json
|
83
|
+
)
|
84
|
+
expect(response).to have_http_status(:ok)
|
85
|
+
expect(response.body).to match_json_schema(:comment)
|
86
|
+
expect(body_to_json('id')).to eq @post.comments.last.id
|
87
|
+
expect(body_to_json('user/id')).to eq @user.id
|
88
|
+
expect(Comment.find_by_id(body_to_json('id'))).to eq @post.comments.last
|
89
|
+
expect(@post.comments.count).to eq(comment_count+1)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "As another user" do
|
94
|
+
|
95
|
+
it "returns http unauthorized" do
|
96
|
+
post api_board_post_comments_path(@board, @post), as: :json, params: valid_attributes
|
97
|
+
expect(response).to have_http_status(:unauthorized)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns http forbidden" do
|
101
|
+
post(
|
102
|
+
api_board_post_comments_path(@board, @post),
|
103
|
+
headers: auth_headers(@user_2),
|
104
|
+
params: valid_attributes,
|
105
|
+
as: :json
|
106
|
+
)
|
107
|
+
expect(response).to have_http_status(:forbidden)
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "Updating my comment on my post" do
|
115
|
+
|
116
|
+
describe "As comment owner" do
|
117
|
+
|
118
|
+
it "updates my comment if user is me" do
|
119
|
+
put(
|
120
|
+
api_board_post_comment_path(@board, @post, @comment),
|
121
|
+
params: valid_attributes,
|
122
|
+
headers: auth_headers(@user),
|
123
|
+
as: :json
|
124
|
+
)
|
125
|
+
expect(response).to have_http_status(:ok)
|
126
|
+
expect(response.body).to match_json_schema(:comment)
|
127
|
+
expect(body_to_json('content')).to eq @comment.reload.content
|
128
|
+
expect(@comment.content).to eq(valid_attributes[:content])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "As another user" do
|
133
|
+
|
134
|
+
it "returns http forbidden if not comment owner" do
|
135
|
+
put(
|
136
|
+
api_board_post_comment_path(@board, @post, @comment),
|
137
|
+
params: valid_attributes,
|
138
|
+
headers: auth_headers(@user_2),
|
139
|
+
as: :json
|
140
|
+
)
|
141
|
+
expect(response).to have_http_status(:forbidden)
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "Deleting my comment on my post" do
|
149
|
+
|
150
|
+
describe "As comment owner" do
|
151
|
+
|
152
|
+
it "Deletes my comment if user is me" do
|
153
|
+
prev_comment_count = @post.comments.count
|
154
|
+
delete(
|
155
|
+
api_board_post_comment_path(@board, @post, @comment),
|
156
|
+
headers: auth_headers(@user),
|
157
|
+
)
|
158
|
+
expect(response).to have_http_status(:ok)
|
159
|
+
expect(@post.comments.count).to eq(prev_comment_count-1)
|
160
|
+
expect(Comment.find_by_id(@comment.id)).to be_nil
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "As another user" do
|
166
|
+
|
167
|
+
it "returns http forbidden if not comment owner" do
|
168
|
+
prev_comment_count = @post.comments.count
|
169
|
+
delete(
|
170
|
+
api_board_post_comment_path(@board, @post, @comment),
|
171
|
+
headers: auth_headers(@user_2),
|
172
|
+
)
|
173
|
+
expect(response).to have_http_status(:forbidden)
|
174
|
+
expect(@post.comments.count).to eq(prev_comment_count)
|
175
|
+
expect(Comment.find_by_id(@comment.id)).not_to be_nil
|
176
|
+
end
|
177
|
+
|
178
|
+
it "Deletes my comment if user is me" do
|
179
|
+
prev_comment_count = @post.comments.count
|
180
|
+
delete(
|
181
|
+
api_board_post_comment_path(@board, @post, @comment),
|
182
|
+
headers: auth_headers(@user),
|
183
|
+
)
|
184
|
+
expect(response).to have_http_status(:ok)
|
185
|
+
expect(@post.comments.count).to eq(prev_comment_count-1)
|
186
|
+
expect(Comment.find_by_id(@comment.id)).to be_nil
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
@@ -14,186 +14,6 @@ RSpec.describe "Api::Board::Post::Comments", type: :request do
|
|
14
14
|
{content: nil}
|
15
15
|
}
|
16
16
|
|
17
|
-
context "Private board" do
|
18
|
-
|
19
|
-
context "Comments on my post" do
|
20
|
-
|
21
|
-
it "returns http unauthorized" do
|
22
|
-
get api_board_post_comments_path(@board, @post)
|
23
|
-
expect(response).to have_http_status(:unauthorized)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "returns http unauthorized" do
|
27
|
-
put api_board_post_comment_path(@board, @post, @comment), params: valid_attributes, as: :json
|
28
|
-
expect(response).to have_http_status(:unauthorized)
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
describe "Get all comments on my post" do
|
33
|
-
describe "As a post owner" do
|
34
|
-
it "returns all comments" do
|
35
|
-
get api_board_post_comments_path(@board, @post), headers: auth_headers(@user)
|
36
|
-
expect(response).to have_http_status(:ok)
|
37
|
-
expect(body_to_json('0')).to match_json_schema(:comment)
|
38
|
-
expect(body_to_json.count).to eq @post.comments.count
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "As another user" do
|
43
|
-
it "returns http forbidden" do
|
44
|
-
get api_board_post_comments_path(@board, @post), headers: auth_headers(@user_2)
|
45
|
-
expect(response).to have_http_status(:forbidden)
|
46
|
-
end
|
47
|
-
|
48
|
-
it "returns http forbidden" do
|
49
|
-
get api_board_post_comments_path(@shared_board, @post), headers: auth_headers(@user_2)
|
50
|
-
expect(response).to have_http_status(:forbidden)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "Creating comment to my post" do
|
57
|
-
|
58
|
-
describe "As post owner" do
|
59
|
-
|
60
|
-
it "returns http unauthorized" do
|
61
|
-
post api_board_post_comments_path(@board, @post), as: :json, params: valid_attributes
|
62
|
-
expect(response).to have_http_status(:unauthorized)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "returns http unprocessable_entity" do
|
66
|
-
post(
|
67
|
-
api_board_post_comments_path(@board, @post),
|
68
|
-
headers: auth_headers(@user),
|
69
|
-
params: invalid_attributes,
|
70
|
-
as: :json
|
71
|
-
)
|
72
|
-
expect(response).to have_http_status(:unprocessable_entity)
|
73
|
-
#todo: assert errors
|
74
|
-
end
|
75
|
-
|
76
|
-
it "creates a new comment" do
|
77
|
-
comment_count = @post.comments.count
|
78
|
-
post(
|
79
|
-
api_board_post_comments_path(@board, @post),
|
80
|
-
headers: auth_headers(@user),
|
81
|
-
params: valid_attributes,
|
82
|
-
as: :json
|
83
|
-
)
|
84
|
-
expect(response).to have_http_status(:ok)
|
85
|
-
expect(response.body).to match_json_schema(:comment)
|
86
|
-
expect(body_to_json('id')).to eq @post.comments.last.id
|
87
|
-
expect(body_to_json('user/id')).to eq @user.id
|
88
|
-
expect(Comment.find_by_id(body_to_json('id'))).to eq @post.comments.last
|
89
|
-
expect(@post.comments.count).to eq(comment_count+1)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
describe "As another user" do
|
94
|
-
|
95
|
-
it "returns http unauthorized" do
|
96
|
-
post api_board_post_comments_path(@board, @post), as: :json, params: valid_attributes
|
97
|
-
expect(response).to have_http_status(:unauthorized)
|
98
|
-
end
|
99
|
-
|
100
|
-
it "returns http forbidden" do
|
101
|
-
post(
|
102
|
-
api_board_post_comments_path(@board, @post),
|
103
|
-
headers: auth_headers(@user_2),
|
104
|
-
params: valid_attributes,
|
105
|
-
as: :json
|
106
|
-
)
|
107
|
-
expect(response).to have_http_status(:forbidden)
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
describe "Updating my comment on my post" do
|
115
|
-
|
116
|
-
describe "As comment owner" do
|
117
|
-
|
118
|
-
it "updates my comment if user is me" do
|
119
|
-
put(
|
120
|
-
api_board_post_comment_path(@board, @post, @comment),
|
121
|
-
params: valid_attributes,
|
122
|
-
headers: auth_headers(@user),
|
123
|
-
as: :json
|
124
|
-
)
|
125
|
-
expect(response).to have_http_status(:ok)
|
126
|
-
expect(response.body).to match_json_schema(:comment)
|
127
|
-
expect(body_to_json('content')).to eq @comment.reload.content
|
128
|
-
expect(@comment.content).to eq(valid_attributes[:content])
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
describe "As another user" do
|
133
|
-
|
134
|
-
it "returns http forbidden if not comment owner" do
|
135
|
-
put(
|
136
|
-
api_board_post_comment_path(@board, @post, @comment),
|
137
|
-
params: valid_attributes,
|
138
|
-
headers: auth_headers(@user_2),
|
139
|
-
as: :json
|
140
|
-
)
|
141
|
-
expect(response).to have_http_status(:forbidden)
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
|
148
|
-
describe "Deleting my comment on my post" do
|
149
|
-
|
150
|
-
describe "As comment owner" do
|
151
|
-
|
152
|
-
it "Deletes my comment if user is me" do
|
153
|
-
prev_comment_count = @post.comments.count
|
154
|
-
delete(
|
155
|
-
api_board_post_comment_path(@board, @post, @comment),
|
156
|
-
headers: auth_headers(@user),
|
157
|
-
)
|
158
|
-
expect(response).to have_http_status(:ok)
|
159
|
-
expect(@post.comments.count).to eq(prev_comment_count-1)
|
160
|
-
expect(Comment.find_by_id(@comment.id)).to be_nil
|
161
|
-
end
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
describe "As another user" do
|
166
|
-
|
167
|
-
it "returns http forbidden if not comment owner" do
|
168
|
-
prev_comment_count = @post.comments.count
|
169
|
-
delete(
|
170
|
-
api_board_post_comment_path(@board, @post, @comment),
|
171
|
-
headers: auth_headers(@user_2),
|
172
|
-
)
|
173
|
-
expect(response).to have_http_status(:forbidden)
|
174
|
-
expect(@post.comments.count).to eq(prev_comment_count)
|
175
|
-
expect(Comment.find_by_id(@comment.id)).not_to be_nil
|
176
|
-
end
|
177
|
-
|
178
|
-
it "Deletes my comment if user is me" do
|
179
|
-
prev_comment_count = @post.comments.count
|
180
|
-
delete(
|
181
|
-
api_board_post_comment_path(@board, @post, @comment),
|
182
|
-
headers: auth_headers(@user),
|
183
|
-
)
|
184
|
-
expect(response).to have_http_status(:ok)
|
185
|
-
expect(@post.comments.count).to eq(prev_comment_count-1)
|
186
|
-
expect(Comment.find_by_id(@comment.id)).to be_nil
|
187
|
-
end
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
end
|
194
|
-
|
195
|
-
end
|
196
|
-
|
197
17
|
context "Shared Board" do
|
198
18
|
|
199
19
|
context "Comments on My Post" do
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
# test scope is @user is owner of the board and owner of the post/s
|
4
|
+
RSpec.describe "Api::Board::Posts", type: :request do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
user_has_many_posts_scenario
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:num_per_page) {
|
11
|
+
20
|
12
|
+
}
|
13
|
+
|
14
|
+
describe "Get Posts" do
|
15
|
+
|
16
|
+
it "return posts" do
|
17
|
+
get api_board_posts_path(@board), headers: auth_headers(@user), params: {page: 1}
|
18
|
+
expect(response).to have_http_status(:ok)
|
19
|
+
expect(body_to_json.count).to eq num_per_page
|
20
|
+
expect(body_to_json('0')).to match_json_schema(:post)
|
21
|
+
expect(get_header("Total").to_i).to eq @num_posts
|
22
|
+
end
|
23
|
+
|
24
|
+
it "return last page" do
|
25
|
+
get api_board_posts_path(@board), headers: auth_headers(@user), params: {page: 2}
|
26
|
+
expect(response).to have_http_status(:ok)
|
27
|
+
expect(body_to_json.count).to eq @num_posts - num_per_page
|
28
|
+
expect(body_to_json('0')).to match_json_schema(:post)
|
29
|
+
expect(get_header("Total").to_i).to eq @num_posts
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|