...
  View open merge request
Commits (17)
......@@ -28,7 +28,7 @@ class V1::ObjectTypesController < ApplicationController
# GET /object_types
# GET /object_types.json
def index
object_types = ObjectType.includes(:mime_types)
object_types = paginate policy_scope(ObjectType).includes(:mime_types)
render json: object_types
end
......@@ -61,23 +61,16 @@ class V1::ObjectTypesController < ApplicationController
end
end
# DELETE /object_types/1
# DELETE /object_types/1.json
def destroy
SafeObjectTypeDestroyService.execute @object_type
render status: :ok
end
private
# Use callbacks to share common setup or constraints between actions.
def set_object_type
@object_type = ObjectType.find(params[:id])
@object_type = policy_scope(ObjectType).includes(:mime_types).find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def object_type_params
params.require(:object_type).permit(:name, mime_types: [])
params.require(:object_type).permit(:name, :image, :status, mime_types: [])
end
# Build mimetypes
......
......@@ -5,28 +5,76 @@
# 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
# it under the terms of the GNU Affero General Public subject as published by
# the Free Software Foundation, either version 3 of the subject, 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.
# GNU Affero General Public subject 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/>.
# You should have received a copy of the GNU Affero General Public subject
# along with portalmec. If not, see <http://www.gnu.org/subjects/>.
class V1::SubjectsController < ApplicationController
include ::Paginator
before_action :authenticate_user!, except: [:show, :destroy, :index]
before_action :set_subject, only: [:show, :update, :destroy]
before_action :authorize!, only: [:update ]
# GET /subjects
# GET /subjects.json
def index
subjects = Subject.all
subjects = paginate policy_scope(Subject)
render json: subjects
end
# GET /subjects/1
# GET /subjects/1.json
def show
render json: @subject
end
# POST /subjects
# POST /subjects.json
def create
@subject = Subject.new(subject_params)
authorize @subject
if @subject.save
render json: @subject, status: :created
else
render json: @subject.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /subjects/1
# PATCH/PUT /subjects/1.json
def update
if @subject.update(subject_params)
render json: @subject, status: :ok
else
render json: @subject.errors, status: :unprocessable_entity
end
end
private
def set_subject
@subject = policy_scope(Subject).find(params[:id])
end
def subject_params
params.require(:subject).permit(:name, :image, :status)
end
def authorize!
authorize @subject
end
end
......@@ -24,4 +24,10 @@ class ObjectType < ApplicationRecord
validates_presence_of :name
validates_uniqueness_of :name
enum status: [:inactive, :active]
has_attached_file :image
validates_attachment_content_type :image, content_type: ['image/svg+xml']
validates_attachment_presence :image
end
......@@ -21,4 +21,10 @@ class Subject < ApplicationRecord
has_many :subject_relations
has_and_belongs_to_many :searches
validates_presence_of :name
enum status: [:inactive, :active]
has_attached_file :image
validates_attachment_content_type :image, content_type: ['image/svg+xml']
validates_attachment_presence :image
end
......@@ -18,6 +18,20 @@
# along with portalmec. If not, see <http://www.gnu.org/licenses/>.
class ObjectTypePolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.nil?
scope.where(status: 'active')
elsif user_can_edit?
scope.all
else
scope.where(status: 'active')
end
end
end
def index?
record
end
......
# 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 SubjectPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.nil?
scope.where(status: 'active')
elsif user_can_edit?
scope.all
else
scope.where(status: 'active')
end
end
end
def create?
record if user_can_edit?
end
def update?
record if user_can_edit?
end
end
\ No newline at end of file
......@@ -19,7 +19,7 @@
class ObjectTypeSerializer < ActiveModel::Serializer
cache key: 'object_type', expires_in: 24.hours
attributes :id, :name
attributes :id, :name, :image, :status
has_many :mime_types
end
# 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 SubjectSerializer < ActiveModel::Serializer
cache key: 'subject', expires_in: 24.hours
attributes :id, :name, :image, :status
end
......@@ -73,7 +73,7 @@ module Portalmec
# end
# end
config.middleware.use Rack::Cors do
config.middleware.insert_before 0, "Rack::Cors" do
allow do
origins '*'
resource '*',
......
......@@ -199,13 +199,14 @@ Rails.application.routes.draw do
resources :languages, except: [:new, :edit]
resources :licenses, except: [:new, :edit]
resources :mime_types, except: [:new, :edit]
resources :object_types, except: [:new, :edit]
resources :object_types, except: [:new, :edit, :destroy]
resources :roles, except: [:new, :edit]
resources :scores, only: [:index, :show, :update]
resources :ratings, except: [:new, :edit]
resources :contacts
resources :suggestions
resources :statistics, only: [:index]
resources :subjects, except: [:destroy]
resources :complaint_reasons, except: [:destroy]
resources :questions, except: [:destroy]
......
class AddImageToSubjects < ActiveRecord::Migration[5.0]
def up
add_attachment :subjects, :image
end
def down
remove_attachment :subjects, :image
end
end
class AddImageToObjectTypes < ActiveRecord::Migration[5.0]
def up
add_attachment :object_types, :image
end
def down
remove_attachment :object_types, :image
end
end
class AddStatusToSubject < ActiveRecord::Migration[5.0]
def change
add_column :subjects, :status, :integer, default: 0
end
end
class AddStatusToObjectTypes < ActiveRecord::Migration[5.0]
def change
add_column :object_types, :status, :integer, default: 0
end
end
\ No newline at end of file
......@@ -27,7 +27,7 @@ resource 'Collections' do
explanation "Collection is a group of educational content or another collection, which an user can show, create, update and destroy."
before { 12.times { create(:collection, privacy: 'public' ); create(:learning_object)}
before { 12.times { create(:collection, privacy: 'public' ); create(:learning_object); create(:subject)}
Collection.reindex
}
......@@ -220,4 +220,5 @@ resource 'Collections' do
end
end
Faker::UniqueGenerator.clear
end
......@@ -23,15 +23,15 @@ resource 'Learning Objects' do
explanation "Learning objects are educational contents (movie, odf, file, sound, etc) which an user can show, create, update and destroy."
before { 12.times { create(:learning_object) }
before { 12.times { create(:learning_object); create(:subject) }
LearningObject.reindex
}
let(:learning_objects) { LearningObject.all }
let(:object_types) { ObjectType.all }
let(:languages) { Language.all }
let(:licenses) { License.all }
let(:subject) { Subject.all }
let(:object_types) {ObjectType.all}
let(:educational_stage) { EducationalStage.all }
let(:tag) { Tag.all }
......@@ -88,7 +88,7 @@ resource 'Learning Objects' do
let(:link) { Faker::Internet.url }
let(:tags) { [ {name: tag.first.name}, {name: tag.last.name} ] }
let(:language_ids) { [ languages.first.id ] }
let(:subjects) { [ subject.first.id] }
let(:subjects) { [subject.first.id] }
let(:educational_stages) { [ educational_stage.first.id ] }
let(:raw_post) { params.to_json }
......@@ -226,4 +226,5 @@ resource 'Learning Objects' do
end
end
Faker::UniqueGenerator.clear
end
......@@ -25,7 +25,7 @@ resource 'Object Type' do
explanation "Object Types are the types of the objects."
before { 12.times { create(:mime_type) } }
before { 12.times { create(:mime_type) }; create(:object_type) }
let(:object_types) { ObjectType.all }
let(:mimetypes) { MimeType.all }
......@@ -54,9 +54,11 @@ resource 'Object Type' do
parameter :name, 'The name of the object type', scope: :object_type
parameter :mime_types, 'Array of mime_types', scope: :object_type
parameter :image, "svg image endoded in base64", scope: :object_type
let(:name) { Faker::Lorem.word }
let(:mime_types) { [ { "id": mimetypes.first.id } ] }
let(:image) {"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iNiIgY3k9IjYiIHI9IjUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4K"}
let(:raw_post) { params.to_json }
example 'Adding an object_type' do
......@@ -65,31 +67,20 @@ resource 'Object Type' do
end
end
delete 'v1/object_types/:id' do
include_context "authenticate_user_admin"
parameter :id, "The id of the object_type"
let(:id) { object_types.first.id }
example 'Destroying an object_type' do
do_request
expect(status).to eq(200)
end
end
put '/v1/object_types/:id' do
include_context "authenticate_user_admin"
parameter :id, "The id of the object_type"
parameter :name, 'The name of the object type', scope: :object_type
parameter :mime_types, 'Array of mime_types', scope: :object_type
parameter :image, "svg image endoded in base64", scope: :object_type
let(:id) { object_types.first.id }
let(:name) { Faker::Lorem.word }
let(:mime_types) { [ { "id": mimetypes.first.id } ] }
let(:image) {"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iNiIgY3k9IjYiIHI9IjUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4K"}
let(:raw_post) { params.to_json }
example 'Updating an object_type' do
......@@ -98,4 +89,5 @@ resource 'Object Type' do
end
end
Faker::UniqueGenerator.clear
end
......@@ -38,8 +38,43 @@ resource 'Subjects' do
end
end
post 'v1/subjects' do
include_context "authenticate_user_admin"
parameter :name, 'The name of the subject', scope: :subject
parameter :image, "svg image endoded in base64", scope: :subject
let(:name) { Faker::Lorem.word }
let(:image) {"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iNiIgY3k9IjYiIHI9IjUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4K"}
let(:raw_post) { params.to_json }
example 'Adding subject' do
do_request
expect(status).to eq(201)
end
end
put 'v1/subjects/:id' do
include_context "authenticate_user_admin"
parameter :id, "identification of one alread registered subject"
parameter :name, 'The name of the subject', scope: :subject
parameter :image, "svg image endoded in base64", scope: :subject
let(:id) {subject.first.id}
let(:name) { Faker::Lorem.word }
let(:image) {"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTIiIHZpZXdCb3g9IjAgMCAxMiAxMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iNiIgY3k9IjYiIHI9IjUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4K"}
let(:raw_post) { params.to_json }
example 'Updating subject' do
do_request
expect(status).to eq(200)
end
end
post 'v1/:type/:id/subjects' do
include_context "authenticate_user"
include_context "authenticate_user_admin"
parameter :id, "The id of the object"
parameter :type, "Represents the type of the object [LearningObject, Collection]"
......@@ -82,4 +117,6 @@ resource 'Subjects' do
expect(status).to eq(200)
end
end
Faker::UniqueGenerator.clear
end
......@@ -26,7 +26,7 @@ resource 'Users' do
explanation "User represents the teacher and students in the system."
before { 12.times { create(:user) }
before { 12.times { create(:user); create(:subject)}
User.reindex
}
......@@ -403,4 +403,6 @@ resource 'Users' do
expect(status).to eq(200)
end
end
Faker::UniqueGenerator.clear
end
......@@ -24,7 +24,7 @@ FactoryGirl.define do
publisher
score { rand(0.0..1.0) }
description { Faker::Lorem.paragraph }
object_type { ObjectType.all.sample }
object_type { FactoryGirl.create :object_type }
language { [Language.all.sample] }
author { Faker::Name.name }
state LearningObject.states[:published]
......
......@@ -18,8 +18,14 @@
# along with portalmec. If not, see <http://www.gnu.org/licenses/>.
FactoryGirl.define do
factory :object_type do |m|
m.name { Faker::Name::name}
m.mime_types { Faker::File.mime_types}
factory :object_type do
name { Faker::Name.unique.name}
mime_types { [FactoryGirl.create(:mime_type)] }
status "active"
image_file_name { "#{Faker::Lorem.word}.svg" }
image_content_type "image/svg+xml"
image_file_size 165
image_updated_at Time.current
end
end
......@@ -17,8 +17,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with portalmec. If not, see <http://www.gnu.org/licenses/>.
include ActionDispatch::TestProcess
FactoryGirl.define do
factory :subject do
name { Faker::Name.name }
name { Faker::Name.unique.name }
status "active"
image_file_name { "#{Faker::Lorem.word}.svg" }
image_content_type "image/svg+xml"
image_file_size 165
image_updated_at Time.current
end
end