diff --git a/app/controllers/concerns/publisher_controller.rb b/app/controllers/concerns/publisher_controller.rb index 1f21ebecb843a44c5dc7949d5c692a788fb01ef2..80f2279202a6d12233c890db2ce84a4af5eb81b7 100644 --- a/app/controllers/concerns/publisher_controller.rb +++ b/app/controllers/concerns/publisher_controller.rb @@ -22,9 +22,9 @@ module PublisherController include Paginator included do - before_action :authenticate, only: [:show_all_drafts, :show_liked_learning_objects, :show_submitted_learning_objects, :show_liked_collections] - before_action :set_publisher, only: [:show_all_drafts, :show_all_learning_objects, :show_submitted_learning_objects, :show_all_collections, :show_liked_learning_objects, :show_liked_collections] - before_action -> { authorize @publisher }, only: [:show_all_drafts, :show_submitted_learning_objects, :show_liked_learning_objects, :show_liked_collections] + before_action :authenticate, only: [:show_all_drafts, :show_liked_learning_objects, :show_submissions, :show_liked_collections] + before_action :set_publisher, only: [:show_all_drafts, :show_all_learning_objects, :show_submissions, :show_all_collections, :show_liked_learning_objects, :show_liked_collections] + before_action -> { authorize @publisher }, only: [:show_all_drafts, :show_submissions, :show_liked_learning_objects, :show_liked_collections] end def show_all_drafts @@ -38,9 +38,20 @@ module PublisherController render json: learning_objects end - def show_submitted_learning_objects - learning_objects = paginate LearningObject.where(publisher: @publisher, state: LearningObject.states[:submitted]) - render json: learning_objects + # GET /v1/users/:id/submissions + def show_submissions + status = params[:status] + if !status.nil? && !Submission.statuses.has_key?(status) && status != 'all' + render json: {"error": "Status not found."}, status: :unprocessable_entity + else + if current_user.is_curator? + submissions = current_user.assignments + else + submissions = current_user.submissions + end + submissions = submissions.where(status: status) unless status.nil? || status == 'all' + render json: paginate(submissions), status: :ok + end end def show_all_collections diff --git a/app/controllers/concerns/submission_controller.rb b/app/controllers/concerns/submission_controller.rb deleted file mode 100644 index 0d1ade4070ad3e502be875793d06976e62c113c6..0000000000000000000000000000000000000000 --- a/app/controllers/concerns/submission_controller.rb +++ /dev/null @@ -1,63 +0,0 @@ - -# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre -# Departamento de Informatica - Universidade Federal do Parana -# -# This file is part of portalmec. -# -# portalmec is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# portalmec is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with portalmec. If not, see <http://www.gnu.org/licenses/>. -module SubmissionController - extend ActiveSupport::Concern - include ::Paginator - - included do - before_action :set_new_submission, only: :submit - before_action :set_submission, only: :show_submission - before_action :authorize! - end - - def submissions - learning_objects = paginate LearningObject.where(state: LearningObject.states[:submitted]) - render json: learning_objects - end - - def submit - return render status: :ok if @learning_object.submitted? - - if @learning_object.update(state: LearningObject.states[:submitted]) - render json: @learning_object, status: :ok - else - render json: @learning_object.errors, status: :unprocessable_entity - end - end - - def show_submission - return render status: :ok if @learning_object.draft? || @learning_object.published? - render json: @learning_object - end - - private - - def submitted - return @learning_object.submitted? - end - - def set_new_submission - @learning_object = LearningObject.find(params[:id]) - end - - def set_submission - @learning_object ||= LearningObject.find(params[:id]) - end - -end diff --git a/app/controllers/v1/learning_objects_controller.rb b/app/controllers/v1/learning_objects_controller.rb index e43ff1a9fb09d470dd07b46debad6ff8dfc1b5cf..7fc2d01a7112d449ee5a1d5845497fe699ca0237 100644 --- a/app/controllers/v1/learning_objects_controller.rb +++ b/app/controllers/v1/learning_objects_controller.rb @@ -28,7 +28,6 @@ class V1::LearningObjectsController < ApplicationController include ::HighlightsController include ::SubjectableController include ::StageableController - include ::SubmissionController before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging, :submit, :submission, :show_submission] before_action :set_learning_object, only: [:show, :update, :destroy, :subjecting, :unsubjecting, :add_stages, :remove_stages] diff --git a/app/controllers/v1/questions_controller.rb b/app/controllers/v1/questions_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..2fa9a3a294589ed6abbac248b4897ef345a78708 --- /dev/null +++ b/app/controllers/v1/questions_controller.rb @@ -0,0 +1,79 @@ +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class V1::QuestionsController < ApplicationController + include ::Paginator + + before_action :authenticate_user!, except: [:destroy, :index] + before_action :set_question, only: [:show, :update, :destroy] + before_action :authorize!, only: [ :update, :destroy ] + + # GET /questions + def index + @questions = paginate Question.all + + render json: @questions + end + + # GET /questions/1 + def show + render json: @question + end + + # POST /questions + def create + @question = Question.new(question_params) + + authorize @question + + if @question.save + render json: @question, status: :created + else + render json: @question.errors, status: :unprocessable_entity + end + end + + # PATCH/PUT /questions/1 + def update + if @question.update(question_params) + render json: @question + else + render json: @question.errors, status: :unprocessable_entity + end + end + + # DELETE /questions/1 + def destroy + @question.destroy + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_question + @question = Question.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def question_params + params.require(:question).permit(:description, :status) + end + + def authorize! + authorize @question + end +end diff --git a/app/controllers/v1/submissions_controller.rb b/app/controllers/v1/submissions_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..dddcb67286fdb93f7e66276f64768036809fb491 --- /dev/null +++ b/app/controllers/v1/submissions_controller.rb @@ -0,0 +1,120 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class V1::SubmissionsController < ApplicationController + include ::Paginator + + before_action :set_new_submission, only: :index + before_action :set_submission, only: [:show, :answer, :destroy] + before_action :authenticate_user! + before_action :authorize!, except: :create + + def index + submissions = paginate Submission.all + render json: submissions + end + + def show + render json: @submission + end + + def create + learning_object = LearningObject.where(id: submission_params[:learning_object_id]).first + if learning_object.blank? + render :json, status: :not_found + else + @submission = Submission.new(learning_object: learning_object, submitter: current_user, status: :submitted) + + authorize @submission + + if @submission.save + CuratorAssignmentsService.new(@submission).assign + @submission.learning_object.submitted! + render json: @submission, status: :created + else + render json: @submission.errors, status: :unprocessable_entity + end + end + end + + # GET /v1/submission/:id/answer + def answer + @submission.justification = answer_params[:justification] + answers = [] + questions = Question.active.pluck(:id) + answers = answer_params[:answers] + if questions.size > answers.size + render json: { "error": "Active questions missing" }, status: :unprocessable_entity + else + answers.each do |answer| + if !questions.include?(answer[:question_id]) + render json: {"error": "Inactive questions not permitted"}, status: :unprocessable_entity + return + else + @submission.answers << Answer.create(answer) + end + end + @submission.curator = current_user + if @submission.save + if @submission.accepted? + publisher = LearningObjectPublisher.new(DspaceService.create_client) + publisher.publish @submission.learning_object + else + @submission.learning_object.destroy + end + render json: @submission, status: :ok + else + render json: @submission.errors, status: :unprocessable_entity + end + end + end + + def destroy + @submission.destroy + response = { 'status': 'deleted' } + render status: :ok, json: response + end + + private + + def answer_params + return nil if params[:submission].nil? + params[:submission].permit(:justification, answers: [:question_id, :accepted]) + end + + def submission_params + return nil if params[:submission].nil? + params[:submission].permit(:learning_object_id) + end + + def set_new_submission + @submission ||= Submission.new + end + + def set_submission + @submission ||= Submission.find_by_id(params[:id]) + if @submission.blank? + render status: :not_found + end + end + + def authorize! + authorize @submission + end +end diff --git a/app/models/answer.rb b/app/models/answer.rb new file mode 100644 index 0000000000000000000000000000000000000000..42a25d21587461cb82e4f4682bc74fe691283a6a --- /dev/null +++ b/app/models/answer.rb @@ -0,0 +1,34 @@ +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +# == Schema Information +# +# Table name: answers + +# t.integer "question_id" +# t.integer "submission_id" +# t.boolean "accepted" +# t.datetime "created_at", null: false +# t.datetime "updated_at", null: false + +class Answer < ApplicationRecord + belongs_to :question + belongs_to :submission + + validates :submission, :question, presence: true +end diff --git a/app/models/curator_assignment.rb b/app/models/curator_assignment.rb new file mode 100644 index 0000000000000000000000000000000000000000..e9d56081d02c8c7be6c1e7462ac733986291d37b --- /dev/null +++ b/app/models/curator_assignment.rb @@ -0,0 +1,40 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +# == Schema Information +# +# Table name: curator_assignments + +# t.integer "submission_id" +# t.integer "user_id" +# t.integer "status", default: 0 +# t.datetime "created_at", null: false +# t.datetime "updated_at", null: false + + +class CuratorAssignment < ApplicationRecord + include Trackable + + enum status: [:assigned, :answered, :ignored] + + belongs_to :submission + belongs_to :user + + validates :submission, :user, presence: true +end diff --git a/app/models/question.rb b/app/models/question.rb new file mode 100644 index 0000000000000000000000000000000000000000..6a4b3c70bfd60b3d603f0f187bb7b9bfc7e1dc6c --- /dev/null +++ b/app/models/question.rb @@ -0,0 +1,33 @@ +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +# == Schema Information +# +# Table name: questions + +# t.string "description" +# t.integer "status", default: 0 +# t.datetime "created_at", null: false +# t.datetime "updated_at", null: false + +class Question < ApplicationRecord + enum status: [:inactive, :active] + + has_many :answers + has_many :submissions, through: :answers +end diff --git a/app/models/submission.rb b/app/models/submission.rb new file mode 100644 index 0000000000000000000000000000000000000000..0cee3ddbb68f51c6044adb0410da17321c702fb7 --- /dev/null +++ b/app/models/submission.rb @@ -0,0 +1,69 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +# == Schema Information +# +# Table name: submissions + +# t.string "justification" +# t.integer "status", default: 0 +# t.datetime "answered_at" +# t.integer "curator_id" +# t.integer "submitter_id", null: false +# t.integer "learning_object_id" +# t.datetime "created_at", null: false +# t.datetime "updated_at", null: false + +class Submission < ApplicationRecord + include Trackable + + enum status: [:submitted, :rejected, :accepted] + + belongs_to :submitter, class_name: "User" + belongs_to :curator, class_name: "User" + belongs_to :learning_object + has_many :curator_assignments, dependent: :destroy + has_many :assignees, through: :curator_assignments, source: :user + has_many :answers, dependent: :destroy + has_many :questions, through: :answers + + validates :submitter, :learning_object, presence: true + + after_update :update_status + + def update_status + if curator_id_changed? + curator_assignments.each do |ca| + if ca.user == curator + ca.answered! + else + ca.ignored! + end + end + + status = answers.all? { |a| a.accepted? } ? :accepted : :rejected + self.update_columns(status: status, answered_at: Time.current) + end + end + + def new_update_activity + return new_activity(:update, {status: self.status}) if status_changed? + nil + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 6973d52cd260ace001f2db59f74307b148b1b906..082014a9dd23b3808aecf5bd4447c2f558bcae36 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -90,6 +90,11 @@ class User < ApplicationRecord has_many :applications has_many :searches + has_many :submissions, class_name: "Submission", foreign_key: "submitter_id" + has_many :curations, class_name: "Submission", foreign_key: "curator_id" + has_many :curator_assignments + has_many :assignments, through: :curator_assignments, source: :submission + after_create :default_role before_save :verify_teacher_id after_save :verify_dspace_info diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 62709b8f622701484ba0590822e9dd91673cd885..1de4215e79276202b27d1aa4b7ae4056cac4605a 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -61,7 +61,7 @@ class ApplicationPolicy return false if user.nil? return true if user_can_edit? - return owner.users.include?(user) if owner.is_a?(Institution) + # return owner.users.include?(user) if owner.is_a?(Institution) owner == user end diff --git a/app/policies/learning_object_policy.rb b/app/policies/learning_object_policy.rb index a3a49e091ecc5c586abf7a9c48833470b0f12970..e37c68a34dc2538ab60aa4c050b327db1ddd4a12 100644 --- a/app/policies/learning_object_policy.rb +++ b/app/policies/learning_object_policy.rb @@ -23,7 +23,6 @@ class LearningObjectPolicy < ApplicationPolicy include TaggablePolicy include SubjectablePolicy include StageablePolicy - include SubmissionPolicy class Scope < Scope def resolve @@ -70,10 +69,8 @@ class LearningObjectPolicy < ApplicationPolicy end def show? - return record if record.published? || ( !user.nil? && user_can_edit? ) + return record if record.published? || ( !user.nil? && (user_can_edit? || user.is_curator?)) return record if user == record.publisher - ## TODO: falta verificar se o +record.publisher+ é uma instituição e +user+ faz parte - # => return owner.users.include?(user) if owner.is_a?(Institution) (???) end def index? diff --git a/app/policies/publisher_policy.rb b/app/policies/publisher_policy.rb index 5df13047229f9888c91ba76bca2937845f97258a..5006a8ce6625ff3c092c4560dc47934a413bf9b5 100644 --- a/app/policies/publisher_policy.rb +++ b/app/policies/publisher_policy.rb @@ -55,6 +55,10 @@ module PublisherPolicy record if same_user? || user_can_edit? end + def show_submissions? + record if user_can_edit? || (same_user? && (user.is_curator? || user.is_submitter?)) + end + def same_user? record == user end diff --git a/app/policies/question_policy.rb b/app/policies/question_policy.rb new file mode 100644 index 0000000000000000000000000000000000000000..d2a96dc8d803303219fe88a3f14da764f5a9265d --- /dev/null +++ b/app/policies/question_policy.rb @@ -0,0 +1,41 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class QuestionPolicy < ApplicationPolicy + + def index? + record + end + + def show? + record + end + + def create? + record if user_can_edit? + end + + def update? + record if user_can_edit? + end + + def destroy? + record if user.is_admin? + end +end diff --git a/app/policies/submission_policy.rb b/app/policies/submission_policy.rb index 8290e6fb315e97632707665f252621f50381a31d..1058791edb1248b7579e85b2c40c6077c29d66eb 100644 --- a/app/policies/submission_policy.rb +++ b/app/policies/submission_policy.rb @@ -16,20 +16,35 @@ # # You should have received a copy of the GNU Affero General Public License # along with portalmec. If not, see <http://www.gnu.org/licenses/>. -module SubmissionPolicy - def submit? - record if owns? && user.is_submitter? - end +class SubmissionPolicy < ApplicationPolicy - def submissions? - return false if user.nil? + def index? record if user_can_curate? end - def show_submission? - return false if user.nil? + def show? + record if user_can_curate? || owns? + end + + def create? + record if user_can_create? + end + + def answer? record if user_can_curate? end + def destroy? + record if record.submitted? && owns? + end + + def owner + record.submitter + end + + def user_can_create? + return user_exists? && user.is_submitter? && record.learning_object.draft? && record.learning_object.publisher == user + end + end diff --git a/app/serializers/question_serializer.rb b/app/serializers/question_serializer.rb new file mode 100644 index 0000000000000000000000000000000000000000..0929458fe4d482cde95b5fd21addfd071bd6d1a6 --- /dev/null +++ b/app/serializers/question_serializer.rb @@ -0,0 +1,26 @@ +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class QuestionSerializer < ActiveModel::Serializer + cache key: 'question', expires_in: 24.hours + + attributes \ + :id, + :description, + :status +end diff --git a/app/serializers/submission_serializer.rb b/app/serializers/submission_serializer.rb new file mode 100644 index 0000000000000000000000000000000000000000..aca8ff3e1e4523f84c6686dbd1b3daaddd1163e0 --- /dev/null +++ b/app/serializers/submission_serializer.rb @@ -0,0 +1,30 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class SubmissionSerializer < ActiveModel::Serializer + cache key: 'submission', expires_in: 4.hours, except: [:status] + + attributes :id, :status, :justification, :answered_at, :created_at + + belongs_to :submitter + belongs_to :curator + belongs_to :learning_object + has_many :curator_assignments + has_many :answers +end diff --git a/app/services/activities_filter_service.rb b/app/services/activities_filter_service.rb index 4039e123f2acaa4d07f2d6a818c79037dcae9b6d..e057b0e6a99b03780ffabbf3126dfd1327348bad 100644 --- a/app/services/activities_filter_service.rb +++ b/app/services/activities_filter_service.rb @@ -34,6 +34,7 @@ module ActivitiesFilterService 'collection.create', 'collection.update', 'collection.destroy', 'collection_item.create', 'collection_item.update', 'collection_item.destroy', 'learning_object.create', 'learning_object.update', 'learning_object.destroy', + 'submission.create', 'submission.update', 'submission.destroy', 'review.create', 'download.create', 'like.create', 'like.destroy' diff --git a/app/services/curator_assignments_service.rb b/app/services/curator_assignments_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..5af9ef9fd49cac4ded03847957fec2cce9b8deb7 --- /dev/null +++ b/app/services/curator_assignments_service.rb @@ -0,0 +1,14 @@ +class CuratorAssignmentsService + + def initialize(submission, old_curators = nil) + @submission = submission + @old_curators = old_curators + + end + def assign + curators = User.joins(:roles).where(roles: {name: "curator"}).left_joins(:curator_assignments).group('"users"."id"').order('COUNT("curator_assignments"."user_id") ASC').where.not(id: @old_curators).first(5) + @submission.assignees << curators + #TODO: notify curators (email?) + end + +end diff --git a/config/routes.rb b/config/routes.rb index eeeab87cae4da0cc93bfdfd449fc86fe689e9b31..c8af17db8269438d4f09980cfc86024bb9abba66 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -77,16 +77,6 @@ Rails.application.routes.draw do end end - concern :submission do - collection do - get :submissions - get 'submissions/:id', action: :show_submission - end - member do - post :submit - end - end - concern :highlights do collection do get :this_week @@ -100,7 +90,7 @@ Rails.application.routes.draw do get 'drafts', as: :get_drafts, action: :show_all_drafts get 'learning_objects', as: :get_learning_objects, action: :show_all_learning_objects get 'learning_objects/liked', as: :get_liked_learning_objects, action: :show_liked_learning_objects - get 'submissions', as: :get_submitted_learning_objects, action: :show_submitted_learning_objects + get 'submissions', as: :get_submissions, action: :show_submissions get 'collections', as: :get_collections, action: :show_all_collections get 'collections/liked', as: :get_liked_collections, action: :show_liked_collections end @@ -166,7 +156,7 @@ Rails.application.routes.draw do end end - resources :learning_objects, concerns: [:sociable, :downloadable, :reviewable, :taggable, :versionable, :deletable, :highlights, :subjectable, :stageable, :submission] do + resources :learning_objects, concerns: [:sociable, :downloadable, :reviewable, :taggable, :versionable, :deletable, :highlights, :subjectable, :stageable] do member do resource :chunk, module: 'learning_objects', only: [:create, :show] resource :upload, module: 'learning_objects', only: :create @@ -184,6 +174,12 @@ Rails.application.routes.draw do end end + resources :submissions, except: :update do + member do + post :answer + end + end + resources :complaints, only: [:index, :create], concerns: :deletable resources :languages, except: [:new, :edit] resources :licenses, except: [:new, :edit] @@ -195,6 +191,7 @@ Rails.application.routes.draw do resources :contacts resources :suggestions resources :statistics, only: [:index] + resources :questions, except: [:destroy] post '/package', to: 'packages#link' get '/subjects', to: 'subjects#index' diff --git a/config/schedule.rb b/config/schedule.rb index 510a0b6006c9095a95fd4808c51a6d9febd88ad7..a70200147d1f756f14b76a5f8d08708c65122c21 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -42,3 +42,8 @@ every 6.hours do rake 'score:calculate_all' end + +#Reassign submitted LO that has expired +every :sunday, at: '3am' do + rake 'submission:reassign' +end \ No newline at end of file diff --git a/db/migrate/20171205140057_remove_learning_object_attachments_foreign_key_on_cascade.rb b/db/migrate/20171205140057_remove_learning_object_attachments_foreign_key_on_cascade.rb index b9cfc308eaa2e795070a93da5631a42e1d342002..ae0c1dde45eda980163d1970a2a9c595b84aec78 100644 --- a/db/migrate/20171205140057_remove_learning_object_attachments_foreign_key_on_cascade.rb +++ b/db/migrate/20171205140057_remove_learning_object_attachments_foreign_key_on_cascade.rb @@ -1,6 +1,24 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class RemoveLearningObjectAttachmentsForeignKeyOnCascade < ActiveRecord::Migration[5.0] def change remove_foreign_key :learning_object_attachments, :learning_object_attachments end end - diff --git a/db/migrate/20180119174926_remove_attachment_id_for_learning_object_attachments.rb b/db/migrate/20180119174926_remove_attachment_id_for_learning_object_attachments.rb index 51448b27813771185e6d1c6f46ce2a982080b4ac..12c1493cee5f816fe8f8d828f542690796b7039f 100644 --- a/db/migrate/20180119174926_remove_attachment_id_for_learning_object_attachments.rb +++ b/db/migrate/20180119174926_remove_attachment_id_for_learning_object_attachments.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class RemoveAttachmentIdForLearningObjectAttachments < ActiveRecord::Migration[5.0] def change remove_index :learning_object_attachments, :attachment_id diff --git a/db/migrate/20180123124526_add_foreign_key_to_learning_object_attachments.rb b/db/migrate/20180123124526_add_foreign_key_to_learning_object_attachments.rb index 159078d60e3bd25da62ac6597b94f47e500a9d27..407f980c0ca89eb55bd74ac8592fc6234a5a7c28 100644 --- a/db/migrate/20180123124526_add_foreign_key_to_learning_object_attachments.rb +++ b/db/migrate/20180123124526_add_foreign_key_to_learning_object_attachments.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddForeignKeyToLearningObjectAttachments < ActiveRecord::Migration[5.0] def change add_column :learning_object_attachments, :learning_object_attachment_id, :integer diff --git a/db/migrate/20180226141521_add_handle_to_user.rb b/db/migrate/20180226141521_add_handle_to_user.rb index dbaabea9cbc28ad473e9f76091283441906fa0b1..2cfa80b17be5490c6a51b454e724f1b06ca6d891 100644 --- a/db/migrate/20180226141521_add_handle_to_user.rb +++ b/db/migrate/20180226141521_add_handle_to_user.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddHandleToUser < ActiveRecord::Migration[5.0] def change add_column :users, :dspace_handle, :string diff --git a/db/migrate/20180302141449_add_dspace_info_to_user.rb b/db/migrate/20180302141449_add_dspace_info_to_user.rb index 99a14bbd6b5737d62c66579494ec6121bb8a2dbc..844e2611ae2cb754c3b3ee78e88a267e61331d1a 100644 --- a/db/migrate/20180302141449_add_dspace_info_to_user.rb +++ b/db/migrate/20180302141449_add_dspace_info_to_user.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddDspaceInfoToUser < ActiveRecord::Migration[5.0] def change add_column :users, :dspace_url, :string diff --git a/db/migrate/20180627133142_add_teacher_id_to_users.rb b/db/migrate/20180627133142_add_teacher_id_to_users.rb index be355daee5068d76034164adf82dc59e6de39afe..c59ead84ff41cb9e9f958a127afb279eb4bb09c9 100644 --- a/db/migrate/20180627133142_add_teacher_id_to_users.rb +++ b/db/migrate/20180627133142_add_teacher_id_to_users.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddTeacherIdToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :teacher_id, :string diff --git a/db/migrate/20180704145600_add_birthday_to_users.rb b/db/migrate/20180704145600_add_birthday_to_users.rb index 59fc52050ba0e738aa23c9eddc6bf22eb5c2cbe6..f1920607c178b4c9e7a74317af694bce5b80f903 100644 --- a/db/migrate/20180704145600_add_birthday_to_users.rb +++ b/db/migrate/20180704145600_add_birthday_to_users.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddBirthdayToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :birthday, :datetime diff --git a/db/migrate/20180905123749_create_schools.rb b/db/migrate/20180905123749_create_schools.rb index 70cde2650842ecbb7982465bf971a6039c01b9f4..93e440eb35e911d2aa6e0341efc2cc05a0014658 100644 --- a/db/migrate/20180905123749_create_schools.rb +++ b/db/migrate/20180905123749_create_schools.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class CreateSchools < ActiveRecord::Migration[5.0] def change create_table :schools do |t| diff --git a/db/migrate/20180906131310_add_teacher_info_to_user.rb b/db/migrate/20180906131310_add_teacher_info_to_user.rb index 2e81b1d6db3684870725ef9820f55a22aa3e4651..f43a20723992d0f1d7fbb58afcfca0414b12714a 100644 --- a/db/migrate/20180906131310_add_teacher_info_to_user.rb +++ b/db/migrate/20180906131310_add_teacher_info_to_user.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddTeacherInfoToUser < ActiveRecord::Migration[5.0] def change add_reference :users, :school, foreign_key: true diff --git a/db/migrate/20181001145219_add_terms_to_learning_object.rb b/db/migrate/20181001145219_add_terms_to_learning_object.rb index 98c076498db4fd091e8862301dce930382f06650..3474899c5f2833d89508e130d5aeec084dbce526 100644 --- a/db/migrate/20181001145219_add_terms_to_learning_object.rb +++ b/db/migrate/20181001145219_add_terms_to_learning_object.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddTermsToLearningObject < ActiveRecord::Migration[5.0] def change add_column :learning_objects, :terms_of_service, :boolean diff --git a/db/migrate/20181002143205_add_theme_to_subjects.rb b/db/migrate/20181002143205_add_theme_to_subjects.rb index 4294452c91e3b514011916b53ad6cbfb9c4d36a0..bb6c515b8b938eccf7e4672d36e7bade64cd770a 100644 --- a/db/migrate/20181002143205_add_theme_to_subjects.rb +++ b/db/migrate/20181002143205_add_theme_to_subjects.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class AddThemeToSubjects < ActiveRecord::Migration[5.0] def change add_column :subjects, :theme, :boolean, default: false diff --git a/db/migrate/20190109124148_fix_user_index.rb b/db/migrate/20190109124148_fix_user_index.rb index 84cdf04e2d6b5c71fed6c73a0b041683aedc137d..329bf25d7deef664d8175ffd81380f630068af1e 100644 --- a/db/migrate/20190109124148_fix_user_index.rb +++ b/db/migrate/20190109124148_fix_user_index.rb @@ -1,3 +1,22 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + class FixUserIndex < ActiveRecord::Migration[5.0] def change remove_index :users, column: :email diff --git a/db/migrate/20190115112645_create_questions.rb b/db/migrate/20190115112645_create_questions.rb new file mode 100644 index 0000000000000000000000000000000000000000..c6627b8da6b4516031aa9c5d1e5fd528e62d1e78 --- /dev/null +++ b/db/migrate/20190115112645_create_questions.rb @@ -0,0 +1,28 @@ +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livrespec/routing/ +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class CreateQuestions < ActiveRecord::Migration[5.0] + def change + create_table :questions do |t| + t.string :description + t.integer :status, default: 0 + + t.timestamps + end + end +end diff --git a/db/migrate/20190115120340_create_submissions.rb b/db/migrate/20190115120340_create_submissions.rb new file mode 100644 index 0000000000000000000000000000000000000000..dadf7bb0cd5946b086ab06ca7ad14a11297accc9 --- /dev/null +++ b/db/migrate/20190115120340_create_submissions.rb @@ -0,0 +1,33 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class CreateSubmissions < ActiveRecord::Migration[5.0] + def change + create_table :submissions do |t| + t.string :justification + t.integer :status, default: 0 + t.datetime :answered_at + t.references :curator, null:true, index: true + t.references :submitter, null:false, index: true + t.references :learning_object, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20190116114551_create_curator_assignments.rb b/db/migrate/20190116114551_create_curator_assignments.rb new file mode 100644 index 0000000000000000000000000000000000000000..b652b976d04a7acb6be0beac43fc6e12e51e45a2 --- /dev/null +++ b/db/migrate/20190116114551_create_curator_assignments.rb @@ -0,0 +1,30 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class CreateCuratorAssignments < ActiveRecord::Migration[5.0] + def change + create_table :curator_assignments do |t| + t.references :submission + t.references :user + t.integer :status, default: 0 + + t.timestamps + end + end +end diff --git a/db/migrate/20190118124055_create_answers.rb b/db/migrate/20190118124055_create_answers.rb new file mode 100644 index 0000000000000000000000000000000000000000..bdabbaf5580869ea7febc28793d25b4bb6d6273e --- /dev/null +++ b/db/migrate/20190118124055_create_answers.rb @@ -0,0 +1,30 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +class CreateAnswers < ActiveRecord::Migration[5.0] + def change + create_table :answers do |t| + t.references :question, foreign_key: true + t.references :submission, foreign_key: true + t.boolean :accepted + + t.timestamps + end + end +end diff --git a/lib/tasks/submission.rake b/lib/tasks/submission.rake new file mode 100644 index 0000000000000000000000000000000000000000..645f813b583754d297e4f9ae2974d3cd7bc566e5 --- /dev/null +++ b/lib/tasks/submission.rake @@ -0,0 +1,13 @@ +namespace :submission do + desc 'Assign not evaluated submission to more curators' + task reassign: :environment do + submissions = Submission.where('status=? AND updated_at<?', Submission.statuses["submitted"], 7.day.ago) + + submissions.each do |s| + old_curators = CuratorAssignment.select("user_id").where(submission_id: s.id) + CuratorAssignmentsService.new(s, old_curators).assign + s.touch + end + end + +end diff --git a/spec/acceptance/downloads_spec.rb b/spec/acceptance/downloads_spec.rb index cbef92a2d220628273da23808728dece02a29606..85e78d15dd7d9d0ce750d0515756fe0599a5267e 100644 --- a/spec/acceptance/downloads_spec.rb +++ b/spec/acceptance/downloads_spec.rb @@ -30,8 +30,8 @@ resource 'Downloads' do get '/v1/:type/:id/download' do include_context "authenticate_user" - parameter :type, "Represents the type of object [‘learning_objects’,'collections']", scope: :download - parameter :id, "The id of object", scope: :download + parameter :type, "Represents the type of object [‘learning_objects’,'collections']" + parameter :id, "The id of object" let(:type) { 'learning_objects' } let(:id) { @learning_object.id } diff --git a/spec/acceptance/learning_objects_spec.rb b/spec/acceptance/learning_objects_spec.rb index 6c832881f13abf9eb2b4dd2fde83f5b8af68028d..48bc7a3999b2ba0f4351d2ce16b0ddf6f302f329 100644 --- a/spec/acceptance/learning_objects_spec.rb +++ b/spec/acceptance/learning_objects_spec.rb @@ -227,45 +227,4 @@ resource 'Learning Objects' do end end - get '/v1/learning_objects/submissions' do - include_context "authenticate_user_curator" - - example 'Get a list of submissions' do - do_request - expect(status).to eq(200) - end - end - - get '/v1/learning_objects/submissions/:id' do - include_context "authenticate_user_curator" - - let(:id) { @learning_object.id } - - before do - @learning_object = create(:learning_object) - @learning_object.update(state: LearningObject.states[:submitted]) - end - - example 'Show a submission' do - do_request - expect(status).to eq(200) - end - end - - post '/v1/learning_objects/:id/submit' do - include_context "authenticate_user_submitter" - - let(:id) { @learning_object.id } - - before do - @learning_object = create(:learning_object, publisher: @user) - @learning_object.update(state: LearningObject.states[:draft]) - end - - example 'Submit a learning object to curator' do - do_request - expect(status).to eq(200) - end - end - end diff --git a/spec/acceptance/searches_spec.rb b/spec/acceptance/searches_spec.rb index 483f75a0436ceb0427285e8ffff4e6b3b354491b..cff91585f5a00d005c7ed38ba0d295d3408e98bf 100644 --- a/spec/acceptance/searches_spec.rb +++ b/spec/acceptance/searches_spec.rb @@ -27,15 +27,15 @@ resource 'Searches' do get '/v1/search' do - parameter :page, 'Results page number' + parameter :page, 'Results page number. Starts from 0.' parameter :results_per_page, 'Number of results per page' - parameter :order, 'How the results should be ordered. Default is by relevance, possible values are: author, publicationasc, publicationdesc, title, likes, downloads, review_average. User order by relevance and name.' - parameter :query, 'The query string to be searched' - parameter :search_class, 'What kind of object are going to be searched: LearningObject, Collection, User' + parameter :order, 'How the results should be ordered. Default is by score, possible values are: author, publicationasc, publicationdesc, title, likes, downloads, review_average, _score. Users can be sorted by name and _score.' + parameter :query, 'The query string to be searched. \'*\' returns all the results.' + parameter :search_class, 'What class of objects are going to be searched. Accepted values: LearningObject, Collection, User' parameter :tags, 'Filter the search by tags, separated by ’&’. Example: tags[]=Biologia&tags[]=Artes' - parameter :subjects, 'Filter the search by subjects, array of ids. Example: subjects[]=1&subjects[]=2' - parameter :educational_stages, 'Filter the search by educational_stages, array of ids. Example: educational_stages[]=1&educational_stages[]=2' - parameter :types, 'Filter the search by Learning Object object types, array of ids. Example: object_types[]=1&object_types[]=2' + parameter :subjects, 'Filter the search by subjects. Receives an array of Subject ids. Example: subjects[]=1&subjects[]=2' + parameter :educational_stages, 'Filter the search by educational_stages. Receives an array of EducationalStage ids. Example: educational_stages[]=1&educational_stages[]=2' + parameter :types, 'Filter the search by the Learning Object types. Receives an array of ObjectType ids. Example: object_types[]=1&object_types[]=2' let(:page) { 0 } diff --git a/spec/acceptance/submissions_spec.rb b/spec/acceptance/submissions_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..bee98ad4db9ca519f73ebdcc1ff643d9834f7f57 --- /dev/null +++ b/spec/acceptance/submissions_spec.rb @@ -0,0 +1,121 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +require 'acceptance_helpers' +require 'shared/contexts' + +resource 'Submissions' do + + explanation "Submissions are requests to publish Learning Objects, which must be accepted by a curator." + + before { 5.times { create(:submission) } } + before { 1.times { create(:question) } } + + # let(:submissions) { Submission.all } + # let(:object_types) { ObjectType.all } + # let(:languages) { Language.all } + # let(:licenses) { License.all } + # let(:subject) { Subject.all } + # let(:educational_stage) { EducationalStage.all } + let(:questions) { Question.all } + + + get '/v1/submissions' do + include_context "authenticate_user_curator" + + example_request 'Get a list of submissions' do + expect(JSON.parse(response_body).map { |o| o['id'] }.sort).to eq(Submission.pluck(:id).sort) + expect(status).to eq(200) + end + end + + get '/v1/submissions/:id' do + include_context "authenticate_user_curator" + + let(:id) { @submission.id } + + before do + @submission = create(:submission) + end + + example_request 'Show a submission' do + expect(JSON.parse(response_body)['id']).to eq(@submission.id) + expect(status).to eq(200) + end + end + + post '/v1/submissions' do + header "Content-Type", "application/json" + include_context "authenticate_user_submitter" + + parameter :learning_object_id, 'ID of the Learning Object to be submitted. Must be a draft owned by the signed in user.', scope: :submission + + before do + @lo = create(:learning_object, publisher: @user) + @lo.draft! + end + + let(:learning_object_id) { @lo.id } + let(:raw_post) { params.to_json } + + example 'Create a submission' do + do_request + expect(status).to eq(201) + end + end + + post '/v1/submissions/:id/answer' do + include_context "authenticate_user_curator" + + parameter :justification, 'Text explaining the given answers.', scope: :submission + parameter :answers, 'Array with each question ID and its answer (true or false).', scope: :submission + + let(:justification) { "justification" } + let(:answers) { [{question_id: questions.first.id, accepted: true}] } + let(:raw_post) { params.to_json } + let(:id) { @submission.id } + + before do + submitter = create(:user, roles: [Role.find_by(name: 'submitter')]) + lo = create(:learning_object, publisher: submitter) + @submission = create(:submission, learning_object: lo, submitter: submitter) + end + + example 'Answer a submission' do + do_request + expect(status).to eq(200) + end + end + + delete '/v1/submissions/:id' do + include_context "authenticate_user_submitter" + + let(:id) { @submission.id } + + before do + lo = create(:learning_object, publisher: @user) + @submission = create(:submission, learning_object: lo, submitter: @user) + end + + example 'Destroying a submission' do + do_request + expect(status).to eq(200) + end + end +end diff --git a/spec/acceptance/users_spec.rb b/spec/acceptance/users_spec.rb index 627bad691afa6b87034237edf3f67d3922b362e1..39192b40b6259a7141fef3153defe4b002428927 100644 --- a/spec/acceptance/users_spec.rb +++ b/spec/acceptance/users_spec.rb @@ -52,7 +52,7 @@ resource 'Users' do get '/v1/users/:id' do let(:id) { users.first.id } - example 'Get an user' do + example 'Get a user' do do_request expect(path).to eq("/v1/users/#{id}") # `:id` is replaced with the value of `id` expect(response_body).to eq(Helper.serialize(User.find(id))) @@ -97,7 +97,7 @@ resource 'Users' do let(:avatar) {""} let(:raw_post) {params.to_json} - example 'Creating an user' do + example 'Creating a user' do do_request expect(status).to eq(200) end @@ -127,13 +127,13 @@ resource 'Users' do let(:password_confirmation) { '12345678' } let(:terms_of_service) { true } let(:avatar) {""} - # TODO role ids con't be changed if user isn't admin, send [] + # TODO role ids con't be chaged if user isn't admin, send [] # when it's a admin send [role.first.id] let(:role_ids) { [] } let(:subjects) { [subject.first.id] } let(:raw_post) {params.to_json} - example 'Updating an user' do + example 'Updating a user' do do_request expect(status).to eq(200) end @@ -183,7 +183,7 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user followers' do + example 'Showing a user followers' do do_request expect(status).to eq(200) end @@ -199,7 +199,7 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user’s received reviews' do + example 'Showing a user’s received reviews' do do_request expect(status).to eq(200) end @@ -229,7 +229,7 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user’s liked collections' do + example 'Showing a user’s liked collections' do do_request expect(status).to eq(200) end @@ -244,7 +244,7 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user’s liked learning objects' do + example 'Showing a user’s liked learning objects' do do_request expect(status).to eq(200) end @@ -259,7 +259,7 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user’s learning objects' do + example 'Showing a user’s learning objects' do do_request expect(status).to eq(200) end @@ -274,7 +274,7 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user’s collections' do + example 'Showing a user’s collections' do do_request expect(status).to eq(200) end @@ -289,31 +289,35 @@ resource 'Users' do let(:id) { @user.id } - example 'Showing an user’s drafts' do + example 'Showing a user’s drafts' do do_request expect(status).to eq(200) end end get '/v1/users/:id/submissions' do - include_context "authenticate_user" + include_context "authenticate_user_submitter" + + parameter :status, 'Filter submissions by the status. Accepted values: accepted, rejected, submitted, all (default).' before do - create(:learning_object, publisher: @user, state: LearningObject.states[:submitted]) + lo = create(:learning_object, publisher: @user, state: LearningObject.states[:submitted]) + create(:submission, submitter: @user, learning_object: lo, status: :submitted) end let(:id) { @user.id } + let(:status) { 'submitted' } - example 'Showing an user’s submissions' do + example 'Showing submissions from a user (curator or submitter)' do do_request - expect(status).to eq(200) + expect(response_status).to eq(200) end end delete '/v1/auth' do include_context "authenticate_user" - example 'Destroying an user' do + example 'Destroying a user' do do_request expect(status).to eq(200) end @@ -339,7 +343,7 @@ resource 'Users' do let(:avatar) {""} let(:raw_post) {params.to_json} - example 'Creating an user by admin' do + example 'Creating a user by admin' do do_request expect(status).to eq(201) end @@ -355,7 +359,7 @@ resource 'Users' do @user = create(:user) end - example 'Destroying an user by admin' do + example 'Destroying a user by admin' do do_request expect(status).to eq(200) end @@ -394,7 +398,7 @@ resource 'Users' do @user = create(:user) end - example 'Add an user teacher' do + example 'Add a user teacher' do do_request expect(status).to eq(200) end diff --git a/spec/controllers/v1/questions_controller_spec.rb b/spec/controllers/v1/questions_controller_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..c25504e9f297f6cdf7dc462f2c20a4437225020f --- /dev/null +++ b/spec/controllers/v1/questions_controller_spec.rb @@ -0,0 +1,147 @@ +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to specify the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. +# +# Compared to earlier versions of this generator, there is very limited use of +# stubs and message expectations in this spec. Stubs are only used when there +# is no simpler way to get a handle on the object needed for the example. +# Message expectations are only used when there is no simpler way to specify +# that an instance is receiving a specific message. +# +# Also compared to earlier versions of this generator, there are no longer any +# expectations of assigns and templates rendered. These features have been +# removed from Rails core in Rails 5, but can be added back in via the +# `rails-controller-testing` gem. + +RSpec.describe QuestionsController, type: :controller do + + # This should return the minimal set of attributes required to create a valid + # Question. As you add validations to Question, be sure to + # adjust the attributes here as well. + let(:valid_attributes) { + skip("Add a hash of attributes valid for your model") + } + + let(:invalid_attributes) { + skip("Add a hash of attributes invalid for your model") + } + + # This should return the minimal set of values that should be in the session + # in order to pass any filters (e.g. authentication) defined in + # QuestionsController. Be sure to keep this updated too. + let(:valid_session) { {} } + + describe "GET #index" do + it "returns a success response" do + question = Question.create! valid_attributes + get :index, params: {}, session: valid_session + expect(response).to be_successful + end + end + + describe "GET #show" do + it "returns a success response" do + question = Question.create! valid_attributes + get :show, params: {id: question.to_param}, session: valid_session + expect(response).to be_successful + end + end + + describe "POST #create" do + context "with valid params" do + it "creates a new Question" do + expect { + post :create, params: {question: valid_attributes}, session: valid_session + }.to change(Question, :count).by(1) + end + + it "renders a JSON response with the new question" do + + post :create, params: {question: valid_attributes}, session: valid_session + expect(response).to have_http_status(:created) + expect(response.content_type).to eq('application/json') + expect(response.location).to eq(question_url(Question.last)) + end + end + + context "with invalid params" do + it "renders a JSON response with errors for the new question" do + + post :create, params: {question: invalid_attributes}, session: valid_session + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to eq('application/json') + end + end + end + + describe "PUT #update" do + context "with valid params" do + let(:new_attributes) { + skip("Add a hash of attributes valid for your model") + } + + it "updates the requested question" do + question = Question.create! valid_attributes + put :update, params: {id: question.to_param, question: new_attributes}, session: valid_session + question.reload + skip("Add assertions for updated state") + end + + it "renders a JSON response with the question" do + question = Question.create! valid_attributes + + put :update, params: {id: question.to_param, question: valid_attributes}, session: valid_session + expect(response).to have_http_status(:ok) + expect(response.content_type).to eq('application/json') + end + end + + context "with invalid params" do + it "renders a JSON response with errors for the question" do + question = Question.create! valid_attributes + + put :update, params: {id: question.to_param, question: invalid_attributes}, session: valid_session + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to eq('application/json') + end + end + end + + describe "DELETE #destroy" do + it "destroys the requested question" do + question = Question.create! valid_attributes + expect { + delete :destroy, params: {id: question.to_param}, session: valid_session + }.to change(Question, :count).by(-1) + end + end + +end diff --git a/spec/factories/answers.rb b/spec/factories/answers.rb new file mode 100644 index 0000000000000000000000000000000000000000..35d5e7ac5edd0351575db9e06d0aeea966b4d50d --- /dev/null +++ b/spec/factories/answers.rb @@ -0,0 +1,27 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + + +FactoryGirl.define do + factory :answer do + question + submission + answer true + end +end diff --git a/spec/factories/curator_assignments.rb b/spec/factories/curator_assignments.rb new file mode 100644 index 0000000000000000000000000000000000000000..426094b2aac4bf229177246886dfd4ca1ca7fc40 --- /dev/null +++ b/spec/factories/curator_assignments.rb @@ -0,0 +1,26 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +FactoryGirl.define do + factory :curator_assignment do + submission + user + status 0 + end +end diff --git a/spec/factories/questions.rb b/spec/factories/questions.rb new file mode 100644 index 0000000000000000000000000000000000000000..a193e456869ecb242836e4295575c322f206af62 --- /dev/null +++ b/spec/factories/questions.rb @@ -0,0 +1,25 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + +FactoryGirl.define do + factory :question do + description { Faker::Lorem.sentence } + status "active" + end +end diff --git a/spec/factories/submissions.rb b/spec/factories/submissions.rb new file mode 100644 index 0000000000000000000000000000000000000000..4b010e795f993d3dfa6f1ce63e6f4678d2cfad7b --- /dev/null +++ b/spec/factories/submissions.rb @@ -0,0 +1,29 @@ + +# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana +# +# This file is part of portalmec. +# +# portalmec is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# portalmec is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with portalmec. If not, see <http://www.gnu.org/licenses/>. + + +FactoryGirl.define do + factory :submission do + justification "MyString" + status "submitted" + answered_at "2019-01-15 10:03:40" + submitter + learning_object + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 5af8daf515412b1a74af28d6a8b04dd7cc4b33f3..81f976adfb85784aaad068d0051e447067f4504f 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -18,7 +18,7 @@ # along with portalmec. If not, see <http://www.gnu.org/licenses/>. FactoryGirl.define do - factory :user, aliases: [:owner, :publisher, :tagger, :followable] do + factory :user, aliases: [:owner, :publisher, :tagger, :followable, :submitter, :curator] do name { Faker::Name.name } email { Faker::Internet.email } description { Faker::Lorem.sentence }