diff --git a/ data-model.png b/ data-model.png new file mode 100644 index 000000000..43855b542 Binary files /dev/null and b/ data-model.png differ diff --git a/ data-model.xml b/ data-model.xml new file mode 100644 index 000000000..1597bf7d9 --- /dev/null +++ b/ data-model.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..b051c6c57 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +client diff --git a/.eslintrc.json b/.eslintrc.json index a28ebd512..f92aa27b1 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,6 +23,29 @@ "semi": [ "error", "always" - ] + ], + "no-template-curly-in-string": [1], + "no-unsafe-negation": [1], + "array-callback-return": [1], + "eqeqeq": [2], + "no-eval": [2], + "no-global-assign": [2], + "no-implied-eval": [2], + "no-script-url": [2], + "no-throw-literal": [2], + "yoda": [1], + "no-path-concat": [2], + "no-process-exit": [2], + "camelcase": [1], + "eol-last": [1], + "no-continue": [1], + "no-nested-ternary": [1], + "no-tabs": [2], + "no-unneeded-ternary": [1], + "object-curly-spacing": [1], + "space-infix-ops": ["error"], + "no-const-assign": [2], + "no-duplicate-imports": [2], + "prefer-template": [1] } } diff --git a/README.md b/README.md index 5f8b6d3d7..70e2d1110 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Runs Talk. `npm test` ### Lint -`npm lint` +`npm run lint` ### Docs `swagger.yaml` diff --git a/models/action.js b/models/action.js new file mode 100644 index 000000000..581108a71 --- /dev/null +++ b/models/action.js @@ -0,0 +1,35 @@ +'use strict'; + +const mongoose = require('../mongoose'); +const uuid = require('uuid'); +const Schema = mongoose.Schema; + +const ActionSchema = new Schema({ + id: { + type: String, + default: uuid.v4, + unique: true + }, + action_type: String, + item_type: String, + item_id: String, + user_id: String +},{ + _id: false, + timestamps: { + createdAt: 'created_at', + updatedAt: 'updated_at' + } +}); + +/** + * Finds an action by the id. + * @param {String} id identifier of the action (uuid) +*/ +ActionSchema.statics.findById = function(id) { + return Action.findOne({id}); +}; + +const Action = mongoose.model('Action', ActionSchema); + +module.exports = Action; diff --git a/models/comment.js b/models/comment.js new file mode 100644 index 000000000..107708a3b --- /dev/null +++ b/models/comment.js @@ -0,0 +1,44 @@ +'use strict'; + +const mongoose = require('../mongoose'); +const uuid = require('uuid'); +const Schema = mongoose.Schema; + +const CommentSchema = new Schema({ + id: { + type: String, + default: uuid.v4, + unique: true + }, + body: { + type: String, + required: [true, 'The body is required.'], + minlength: 50 + }, + asset_id: String, + author_id: String, + status: { + type: String, + enum: ['accepted', 'rejected', ''], + default: '' + }, + parent_id: String +},{ + _id: false, + timestamps: { + createdAt: 'created_at', + updatedAt: 'updated_at' + } +}); + +/** + * Finds a comment by the id. + * @param {String} id identifier of the comment (uuid) +*/ +CommentSchema.statics.findById = function(id) { + return Comment.findOne({id}); +}; + +const Comment = mongoose.model('Comment', CommentSchema); + +module.exports = Comment; diff --git a/models/user.js b/models/user.js new file mode 100644 index 000000000..d6b174075 --- /dev/null +++ b/models/user.js @@ -0,0 +1,37 @@ +'use strict'; + +const mongoose = require('../mongoose'); +const uuid = require('uuid'); +const Schema = mongoose.Schema; + +const UserProfileSchema = new Schema({ + id: { + type: String, + default: uuid.v4, + unique: true + }, + display_name: String, + auth_user_id: String +},{ + _id: false, + timestamps: { + createdAt: 'created_at', + updatedAt: 'updated_at' + } +}); + +/** + * Finds a user by the id. + * @param {String} id identifier of the user (uuid) +*/ +UserProfileSchema.statics.findById = function(id) { + return UserProfile.findOne({id}); +}; + +// TO DO: methods +// modifications to user as statics +// find by auth user id + +const UserProfile = mongoose.model('UserProfile', UserProfileSchema); + +module.exports = UserProfile; diff --git a/package.json b/package.json index 632135005..b7fb48d34 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,25 @@ "description": "A commenting platform from The Coral Project. https://coralproject.net", "main": "app.js", "scripts": { - "lint": "eslint .", "start": "./bin/www", + "lint": "eslint .", + "pretest": "npm install", + "test": "mocha tests", "embed-start": "node client/coral-embed-stream/dev-server.js" }, + "config": { + "pre-git": { + "commit-msg": [], + "pre-commit": [ + "npm run lint" + ], + "pre-push": [ + "npm test" + ], + "post-commit": [], + "post-merge": [] + } + }, "repository": { "type": "git", "url": "git+https://github.com/coralproject/talk.git" @@ -41,11 +56,15 @@ "babel-preset-es2015": "6.13.0", "babel-preset-es2015-minimal": "^2.1.0", "babel-preset-stage-0": "^6.16.0", + "chai": "^3.5.0", "copy-webpack-plugin": "^3.0.1", + "eslint": "^3.9.1", "exports-loader": "^0.6.3", "immutable": "^3.8.1", "imports-loader": "^0.6.5", "json-loader": "^0.5.4", + "mocha": "^3.1.2", + "pre-git": "^3.10.0", "pym.js": "^1.1.1", "react": "15.3.2", "react-dom": "15.3.2", @@ -53,6 +72,7 @@ "redux": "^3.6.0", "redux-thunk": "^2.1.0", "regenerator": "^0.8.46", + "supertest": "^2.0.1", "timeago.js": "^2.0.3", "webpack": "^1.13.2", "webpack-dashboard": "^0.2.0", diff --git a/swagger.yaml b/swagger.yaml index 3c154c6f7..a7fdc973d 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -11,35 +11,204 @@ produces: - application/json paths: /comments: - get: - summary: Comment Types - description: | - This endpoint retrieves comments + # get: + # tags: + # - Comments + # produces: + # - application/json + # summary: Comment Types + # description: | + # This endpoint retrieves comments + # parameters: + # - name: id + # in: query + # description: Comment by id + # required: false + # type: string + # responses: + # 200: + # description: An array of comments + # schema: + # type: array + # items: + # $ref: '#/definitions/Comment' + post: + description: Add a new comment parameters: - - name: id - in: query - description: Comment by id - required: false - type: string - tags: - - Products + - name: body + in: body + description: Body + required: true + schema: + $ref: '#/definitions/Comment' responses: - 200: - description: An array of comments + 201: + description: "OK: Comment Added" + schema: + $ref: '#/definitions/Comment' + 500: + description: "Error" + /comments/{comment_id}/actions: + post: + tags: + - Comments + description: Add a action + parameters: + - name: comment_id + in: path + description: Comment ID + required: true + type: string + - name: body + in: body + description: comment + required: true + schema: + $ref: '#/definitions/Action' + responses: + 201: + description: Action Added schema: type: array items: $ref: '#/definitions/Comment' + /comments/{comment_id}/status: + post: + tags: + - Comments + description: Add a new status + parameters: + - name: comment_id + in: path + description: Comment ID + required: true + type: string + - name: body + in: body + description: comment + required: true + schema: + $ref: '#/definitions/ModerationAction' + responses: + 204: + description: ModerationAction Added + /queue: + get: + tags: + - Queue + description: Queue + parameters: + - name: type + in: query + description: + "pending: no status | flagged: flagged action + no status | rejected: rejected status" + required: true + type: string + enum: + - pending + - flagged + - rejected + - name: limit + in: query + description: Queue limit + required: false + type: integer + - name: skip + in: query + description: Skip + required: false + type: integer + responses: + 200: + description: ModerationAction Added + schema: + type: array + items: + $ref: '#/definitions/ModerationAction' + /stream: + get: + tags: + - Stream + description: Stream + parameters: + - name: asset_id + in: query + description: Description + required: true + type: string + responses: + 200: + description: OK + schema: + type: array + items: + $ref: '#/definitions/Item' + /settings: + get: + tags: + - Settings + description: Settings + responses: + 200: + description: OK + put: + tags: + - Settings + description: Settings + responses: + 204: + description: OK + + + definitions: + Item: + type: object + ModerationAction: + type: string Comment: type: object properties: id: type: string description: Unique identifier - description: + body: type: string - description: Description of comment. - display_name: + description: Description of comment + created_at: + type: string + format: date-time + description: Display name of comment + updated_at: + type: string + format: date-time + description: Display name of comment + user_id: + type: string + description: Display name of comment + parent_id: + type: string + description: Display name of comment + asset_id: + type: string + description: Display name of comment + Actions: + type: object + properties: + item_id: + type: string + item_type: + type: string # comment, user... + type: + type: string # flagged, likes, upvotes... + count: + type: integer + current_user: + type: boolean + Action: + type: object + properties: + type: + type: string + user_id: type: string - description: Display name of comment. diff --git a/tests/index.js b/tests/index.js new file mode 100644 index 000000000..0a212b7a4 --- /dev/null +++ b/tests/index.js @@ -0,0 +1,12 @@ +/* eslint-env node, mocha */ +'use strict'; + +const expect = require('chai').expect; + +describe('Comment', () => { + describe.only('#add', () => { + it('should add a comment', () => { + expect(0).to.be.equal(0); + }); + }); +});