From 2f4ae24ba82ac588f2d4517310717a7dc1eaea8e Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 10 Aug 2021 20:01:50 -0300 Subject: [PATCH 01/19] =?UTF-8?q?=F0=9F=93=9D=20Instru=C3=A7=C3=B5es=20da?= =?UTF-8?q?=20Sprint=20pro=20Azul?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/role.rb | 4 ++-- app/models/team.rb | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/models/role.rb b/app/models/role.rb index 2f5af93..8f7c678 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,9 +1,9 @@ class Role < ApplicationRecord has_many :member_roles has_many :members, through: :member_roles - has_many :children, class_name: 'Role', foreign_key: 'parent_id' belongs_to :team - belongs_to :parent, class_name: 'Role', optional: true + # Adicionar flag que identifica se o cargo é de um 'leader' + # Dica: Criar migration para adicionar atributo 'leader' do tipo 'boolean' include SoftDeletable diff --git a/app/models/team.rb b/app/models/team.rb index 2c33e06..048dd94 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -1,9 +1,22 @@ class Team < ApplicationRecord has_many :members, through: :roles has_many :roles, dependent: :destroy + + belongs_to :parent, class_name: 'Team', optional: true + has_many :children, class_name: 'Team', foreign_key: 'parent_id' include SoftDeletable validates :name, uniqueness: true, presence: true + # Validar se apenas um cargo (ou nenhum) tem a flag de 'leader' + # Dica: Usar método 'validate' como: + # + # validate :has_a_single_leader + # + # private + # + # def has_a single_leader + # errors.add(:roles, 'Não pode ter mais de um líder') unless # Seu código aqui + # end end From a444a6985b481a10136013a78f5527945e63f27e Mon Sep 17 00:00:00 2001 From: Valentin Date: Fri, 20 Aug 2021 13:55:35 -0300 Subject: [PATCH 02/19] =?UTF-8?q?=E2=9C=85=20Remove=20necessidade=20do=20u?= =?UTF-8?q?su=C3=A1rio=20ter=20um=20nome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/user.rb | 3 +-- spec/models/user_spec.rb | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 8cb71e7..15a05a4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,8 +1,7 @@ class User < ApplicationRecord has_secure_password has_one :member - - validates :name, presence: true + validates :email, presence: true, uniqueness: true def is_admin? diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d1f2d15..220a836 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -8,10 +8,10 @@ expect(user).to be_valid end - it "is not valid if the name is blank" do - new_user = build(:user, email: "popao@gmail.com", name: nil) - expect(new_user).to_not be_valid - end + # it "is not valid if the name is blank" do + # new_user = build(:user, email: "popao@gmail.com", name: nil) + # expect(new_user).to_not be_valid + # end it "is not valid if the email has already been taken" do new_user = build(:user, name: "Valentin Ferreira Paes") From daa01b441545438f8d8ccbb96680bde733167ef4 Mon Sep 17 00:00:00 2001 From: Valentin Date: Fri, 20 Aug 2021 14:35:04 -0300 Subject: [PATCH 03/19] =?UTF-8?q?=F0=9F=93=9DInclu=C3=ADda=20documenta?= =?UTF-8?q?=C3=A7=C3=A3o=20do=20Insomnia=20(WiP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support/cgr_api_insomnia_doc.yaml | 218 ++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 support/cgr_api_insomnia_doc.yaml diff --git a/support/cgr_api_insomnia_doc.yaml b/support/cgr_api_insomnia_doc.yaml new file mode 100644 index 0000000..58ca48a --- /dev/null +++ b/support/cgr_api_insomnia_doc.yaml @@ -0,0 +1,218 @@ +openapi: 3.0.0 +info: + description: "Esse documento lista e exemplifica as requisições da API do + sistema CGR." + + version: 0.1.0 + title: CGR - API +tags: + - name: member + description: membros + - name: team + description: times + - name: role + description: cargos + - name: user + description: usuários + - name: authentication + description: autenticação +paths: + /member: + post: + tags: + - member + summary: Cadastra um novo membro + description: "" + operationId: createMember + requestBody: + $ref: "#/components/requestBodies/Member" + responses: + "200": + description: Criado com sucesso + content: + application/json: + schema: + $ref: "#/components/schemas/Member-Response" + "405": + description: Invalid input + put: + tags: + - member + summary: Atualiza os dados de um membro cadastrado + description: "" + operationId: updateMember + requestBody: + $ref: "#/components/requestBodies/Member" + "200": + description: Atualizado com sucesso + content: + application/json: + schema: + $ref: "#/components/schemas/Member-Response" + "405": + description: Invalid input +components: + requestBodies: + Member: + content: + application/json: + schema: + $ref: "#/components/schemas/Member" + description: Um membro que partipa(ou) da empresa. + required: true + schemas: + Member: + type: object + required: + - name + properties: + member: + type: object + properties: + name: + type: string + example: Alice da Costa Borges + deleted-at: + type: string + format: date-time + example: null + hard_delete: + type: boolean + example: false + description: \[PERIGO!\] Informa se o membro da requisição deve ser apagado. + roles: + type: array + items: + type: object + properties: + id: + type: integer + format: int64 + example: 1 + leave_role: + description: Informa se a operação relativa ao cargo deve ser participar + (false), ou sair (true) + type: boolean + example: false + Member-Response: + type: object + required: + - name + properties: + id: + type: integer + format: int64 + example: 1 + user_id: + type: integer + format: int64 + example: null + name: + type: string + example: Alice da Costa Borges + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + deleted_at: + type: string + format: date-time + example: null + Team: + type: object + required: + - name + properties: + id: + type: integer + format: int64 + name: + type: string + example: Núcleo de Talentos + initials: + type: string + example: NUT + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + deleted_at: + type: string + format: date-time + Role: + type: object + required: + - team_id + - name + properties: + team_id: + type: integer + format: int64 + example: 1 + name: + type: string + example: Consultor de Talentos + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + deleted_at: + type: string + format: date-time + example: null + MemberRole: + type: object + required: + - role_id + - member_id + properties: + id: + type: integer + format: int64 + member_id: + type: integer + format: int64 + role_id: + type: integer + format: int64 + entry_date: + type: string + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + deleted_at: + type: string + format: date-time + User: + type: object + required: + - id + - email + properties: + id: + type: integer + format: int64 + name: + type: string + example: Larissa Andrade + member_id: + type: integer + format: int64 + admin: + type: boolean + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time \ No newline at end of file From c5f6b2b89d2acbe6a96b889828125cd69d0132b4 Mon Sep 17 00:00:00 2001 From: Valentin Date: Fri, 20 Aug 2021 17:15:31 -0300 Subject: [PATCH 04/19] =?UTF-8?q?=E2=9C=A8=20Pode=20criar=20times=20com=20?= =?UTF-8?q?cargos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/teams_controller.rb | 19 ++++++++++++---- app/services/team_manager/registrate.rb | 29 +++++++++++++++++++++++++ spec/requests/teams_spec.rb | 12 ++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 app/services/team_manager/registrate.rb diff --git a/app/controllers/teams_controller.rb b/app/controllers/teams_controller.rb index 4efa304..cd0d0e3 100644 --- a/app/controllers/teams_controller.rb +++ b/app/controllers/teams_controller.rb @@ -1,6 +1,8 @@ class TeamsController < ApplicationController before_action :set_team, only: [:show, :update, :destroy] + include TeamManager + # GET /teams def index @teams = Team.all @@ -15,12 +17,12 @@ def show # POST /teams def create - @team = Team.new(team_params) + result = TeamManager::Registrate.call(team_params, roles_params) - if @team.save - render json: @team, status: :created, location: @team + if result.success? + render json: result.team, status: :created, location: result.team else - render json: @team.errors, status: :unprocessable_entity + render json: result.errors, status: :unprocessable_entity end end @@ -52,4 +54,13 @@ def set_team def team_params params.require(:team).permit(:name, :initials) end + + def roles_params + roles = params.fetch(roles, []) + roles_params = [] + roles.each do |r| + roles_params += r.permit(:name, :leader) + end + roles_params + end end diff --git a/app/services/team_manager/registrate.rb b/app/services/team_manager/registrate.rb new file mode 100644 index 0000000..f5e9522 --- /dev/null +++ b/app/services/team_manager/registrate.rb @@ -0,0 +1,29 @@ +module TeamManager + class Registrate < ApplicationService + + def initialize(team_params = {}, roles_params = []) + @team = Team.new(team_params) + @roles_params = roles_params + end + + def execute + return OpenStruct.new( success?: false, + team: nil, + errors: @team.errors) unless create_team + OpenStruct.new(success?: true, team: @team, errors: nil) + end + + private + + def create_team + return unless @team.save + unless @roles_params.empty? + @roles_params.each do |role_params| + Role.create(name: role_params[:name], team: @team) + end + @team.reload + end + @team + end + end +end \ No newline at end of file diff --git a/spec/requests/teams_spec.rb b/spec/requests/teams_spec.rb index 0a6015b..a7d0aaa 100644 --- a/spec/requests/teams_spec.rb +++ b/spec/requests/teams_spec.rb @@ -15,6 +15,18 @@ expect(response).to have_http_status(:created) end + it "creates a Team with a role" do + headers = { "ACCEPT" => "application/json" } + team = { :name => "Núcleo de Organização Empresarial", + :initials => "NOE" } + role = { :name => "Assessor de Organização Empresarial"} + post "/teams", :params => { :team => team, :roles => [ role ] }, :headers => headers + + expect(response.content_type).to match(/application\/json/) + expect(response).to have_http_status(:created) + end + + it "shows all Teams information" do get "/teams" From 62226fb9f589f8f7a14d167d530fd0ee5a8ee726 Mon Sep 17 00:00:00 2001 From: joaopedroazul Date: Tue, 31 Aug 2021 20:29:14 -0300 Subject: [PATCH 05/19] :bug: Fix Bug: only admin can create users --- app/controllers/users_controller.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 764b0e7..0eadec5 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,6 +1,6 @@ class UsersController < ApplicationController before_action :set_user, only: [:show, :update, :destroy] - before_action :authenticate_user, only: [:update, :destroy] + before_action :authenticate_user, only: [:create, :update, :destroy] include UserManager @@ -16,8 +16,11 @@ def show # POST /users def create - result = UserManager::Registrate.call(user_params, member_params) - + if @current_user.is_admin? + result = UserManager::Registrate.call(user_params, member_params) + else + result = false + end if result.success? render json: result.user, include: [:member], status: :created, location: result.user else From 2a29f4c3c4d7f32348e7ef5fbe24984dfbbd0b1a Mon Sep 17 00:00:00 2001 From: Pedro Henrique dos Santos Date: Fri, 3 Sep 2021 15:11:33 -0300 Subject: [PATCH 06/19] =?UTF-8?q?=F0=9F=90=9B=20Atualiza=20metodo=20check?= =?UTF-8?q?=20role=20do=20member=20manager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/member_manager/member_service.rb | 24 +++++++++++++++++++ app/services/member_manager/registrate.rb | 12 ++-------- app/services/member_manager/update.rb | 12 +--------- 3 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 app/services/member_manager/member_service.rb diff --git a/app/services/member_manager/member_service.rb b/app/services/member_manager/member_service.rb new file mode 100644 index 0000000..38018a1 --- /dev/null +++ b/app/services/member_manager/member_service.rb @@ -0,0 +1,24 @@ +module MemberManager + class MemberService < ApplicationService + + protected + + def check_roles + @options[:join_roles] ||= [] + @options[:leave_roles] ||= [] + + return @member.join_role(@defaults[:role].id) unless @options[:join_roles].any? || @options[:leave_roles].any? + + @options[:join_roles].each do |role_id| + @member.join_roles(role_id) + end + + @options[:leave_roles].each do |role_id| + @member.leave_roles(role_id) + end + + @member.reload + end + + end +end \ No newline at end of file diff --git a/app/services/member_manager/registrate.rb b/app/services/member_manager/registrate.rb index 413de21..73d63fa 100644 --- a/app/services/member_manager/registrate.rb +++ b/app/services/member_manager/registrate.rb @@ -1,5 +1,5 @@ module MemberManager - class Registrate < ApplicationService + class Registrate < MemberService attr_reader :member, :options @@ -14,7 +14,7 @@ def execute return OpenStruct.new( success?: false, member: nil, errors: @member.errors) unless @member.save - check_role + check_roles OpenStruct.new(success?: true, member: @member, errors: nil) end @@ -26,13 +26,5 @@ def set_defaults @defaults[:role] = Role.find_or_create_by({name: 'Visitante', team: @defaults[:team]}) end - def check_role - return @member.join_role(@defaults[:role].id) unless @options[:roles] - - @options[:roles].each do |role| - @member.join_role(role[:id]) - end - end - end end \ No newline at end of file diff --git a/app/services/member_manager/update.rb b/app/services/member_manager/update.rb index bb3113b..8b0c49f 100644 --- a/app/services/member_manager/update.rb +++ b/app/services/member_manager/update.rb @@ -1,6 +1,5 @@ module MemberManager - class Update < ApplicationService - + class Update < MemberService attr_reader :current_user, :member, :member_params def initialize(current_user, member, params = {}, options = {}) @@ -39,15 +38,6 @@ def set_defaults @defaults[:role] = Role.find_or_create_by({name: 'Visitante', team: @defaults[:team]}) end - def check_roles - return @member.join_role(@defaults[:role].id) unless @options[:roles] - - @options[:roles].each do |role| - role[:leave_role] ? @member.leave_role(role[:id]) : @member.join_role(role[:id]) - end - @member.reload - end - # Para atualizar as informações de um membro, o usuário deve ser admin # ou o próprio membro que está sendo editado. def can_update? From 341065b91aaf0c2ab964bf91b120118e9cda116d Mon Sep 17 00:00:00 2001 From: Pedro Henrique dos Santos Date: Fri, 3 Sep 2021 15:12:31 -0300 Subject: [PATCH 07/19] =?UTF-8?q?=E2=9C=A8=20Atualiza=20parametros=20das?= =?UTF-8?q?=20requisi=C3=A7=C3=B5es=20de=20member?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/members_controller.rb | 3 ++- app/controllers/users_controller.rb | 4 ++-- app/models/member.rb | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 443fa48..637c3c9 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -18,6 +18,7 @@ def show # POST /members def create result = MemberManager::Registrate.call(member_params, opt_params) + if result.success? render json: result.member, include: [:teams, :roles], status: :created, location: result.member @@ -63,7 +64,7 @@ def member_params end def opt_params - params.permit(:hard_delete, roles: [:id, :leave_role]) + params.permit(:hard_delete, join_roles: [], leave_roles: []) end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 0eadec5..ada3b71 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -60,8 +60,8 @@ def user_params def member_params member_params = { - member: params.fetch(:member, {}).permit(:name, :deleted_at), - options: params.permit(:role_id, :leave_role, :hard_delete) + member: params.fetch(:member, {}).permit(:name), + options: params.permit(:join_roles, :leave_roles, :hard_delete) } member_params ? member_params : nil diff --git a/app/models/member.rb b/app/models/member.rb index 61eb690..4eb8a2c 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -12,6 +12,10 @@ def join_role(role_id) MemberRole.find_or_create_by!({member_id: self.id, role_id: role_id}) end + def join_roles(role_ids) + join_role(role_ids) + end + def leave_role(role_id) relation = MemberRole.where({member_id: self.id, role_id: role_id}) relation = relation.first @@ -20,4 +24,10 @@ def leave_role(role_id) end end + def leave_roles(role_ids) + leave_role(role_ids) + end + + + end From 812d796960438df8ab993371299271216eb6713e Mon Sep 17 00:00:00 2001 From: Pedro Henrique dos Santos Date: Fri, 3 Sep 2021 15:14:12 -0300 Subject: [PATCH 08/19] =?UTF-8?q?=F0=9F=90=9B=20Remove=20recurs=C3=A3o=20d?= =?UTF-8?q?e=20cargos=20e=20adiciona=20em=20times?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/role.rb | 1 + db/migrate/20200722172237_create_teams.rb | 1 + db/migrate/20200722172245_create_roles.rb | 1 - db/schema.rb | 13 ++++++++----- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/models/role.rb b/app/models/role.rb index 8f7c678..e0df8e6 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -2,6 +2,7 @@ class Role < ApplicationRecord has_many :member_roles has_many :members, through: :member_roles belongs_to :team + # Adicionar flag que identifica se o cargo é de um 'leader' # Dica: Criar migration para adicionar atributo 'leader' do tipo 'boolean' diff --git a/db/migrate/20200722172237_create_teams.rb b/db/migrate/20200722172237_create_teams.rb index d20df68..91fc13e 100644 --- a/db/migrate/20200722172237_create_teams.rb +++ b/db/migrate/20200722172237_create_teams.rb @@ -1,6 +1,7 @@ class CreateTeams < ActiveRecord::Migration[5.2] def change create_table :teams do |t| + t.belongs_to :parent, foreign_key: { to_table: :teams } t.string :name t.string :initials diff --git a/db/migrate/20200722172245_create_roles.rb b/db/migrate/20200722172245_create_roles.rb index b2d6a1a..d596041 100644 --- a/db/migrate/20200722172245_create_roles.rb +++ b/db/migrate/20200722172245_create_roles.rb @@ -1,7 +1,6 @@ class CreateRoles < ActiveRecord::Migration[5.2] def change create_table :roles do |t| - t.belongs_to :parent, foreign_key: { to_table :roles } t.references :team, foreign_key: true t.string :name diff --git a/db/schema.rb b/db/schema.rb index 325b9b4..806d21a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,11 +2,11 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. @@ -36,11 +36,13 @@ end create_table "roles", force: :cascade do |t| + t.bigint "parent_id" t.bigint "team_id" t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.datetime "deleted_at" + t.index ["parent_id"], name: "index_roles_on_parent_id" t.index ["team_id"], name: "index_roles_on_team_id" end @@ -64,5 +66,6 @@ add_foreign_key "member_roles", "members" add_foreign_key "member_roles", "roles" add_foreign_key "members", "users" + add_foreign_key "roles", "roles", column: "parent_id" add_foreign_key "roles", "teams" end From ba2f239dcbb73ae9a62ed20366942e96f24cc623 Mon Sep 17 00:00:00 2001 From: Pedro Henrique dos Santos Date: Fri, 3 Sep 2021 15:40:29 -0300 Subject: [PATCH 09/19] =?UTF-8?q?=E2=9C=A8=20Atualiza=20join=5Froles=20e?= =?UTF-8?q?=20leave=5Froles=20como=20arrays?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index ada3b71..14fad72 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -61,7 +61,7 @@ def user_params def member_params member_params = { member: params.fetch(:member, {}).permit(:name), - options: params.permit(:join_roles, :leave_roles, :hard_delete) + options: params.permit(:hard_delete, join_roles: [], leave_roles: []) } member_params ? member_params : nil From a23fa854ac0d11bd74673658a4bf9685ecf1db28 Mon Sep 17 00:00:00 2001 From: joaopedroazul Date: Mon, 13 Sep 2021 18:08:58 -0300 Subject: [PATCH 10/19] =?UTF-8?q?:heavy=5Fcheck=5Fmark:=20Nova=20coluna=20?= =?UTF-8?q?Flag=20criada=20na=20tabela=20Role,=20valida=C3=A7=C3=B5es=20de?= =?UTF-8?q?ssa=20coluna=20tamb=C3=A9m=20foram=20criadas.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/role.rb | 2 ++ db/migrate/20210913205929_add_flag_to_roles.rb | 5 +++++ db/schema.rb | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20210913205929_add_flag_to_roles.rb diff --git a/app/models/role.rb b/app/models/role.rb index e0df8e6..7d83fd5 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -10,4 +10,6 @@ class Role < ApplicationRecord validates :name, presence: true validates :team, presence: true + validates :flag, presence: true + end diff --git a/db/migrate/20210913205929_add_flag_to_roles.rb b/db/migrate/20210913205929_add_flag_to_roles.rb new file mode 100644 index 0000000..70e7d28 --- /dev/null +++ b/db/migrate/20210913205929_add_flag_to_roles.rb @@ -0,0 +1,5 @@ +class AddFlagToRoles < ActiveRecord::Migration[6.1] + def change + add_column :roles, :leader, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 806d21a..69b6429 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_08_30_155133) do +ActiveRecord::Schema.define(version: 2021_09_13_205929) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -42,6 +42,7 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.datetime "deleted_at" + t.boolean "leader" t.index ["parent_id"], name: "index_roles_on_parent_id" t.index ["team_id"], name: "index_roles_on_team_id" end From 5bbde3785726d933a8875e73eab6bbd1a46734ae Mon Sep 17 00:00:00 2001 From: joaopedroazul Date: Mon, 13 Sep 2021 19:11:51 -0300 Subject: [PATCH 11/19] :bug: Fix-Bug: Corrigindo o bug na model role --- app/models/role.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/role.rb b/app/models/role.rb index 7d83fd5..fe3ac61 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -10,6 +10,6 @@ class Role < ApplicationRecord validates :name, presence: true validates :team, presence: true - validates :flag, presence: true + validates :leader, presence: true end From 49611f3fed91b9c3ddc53be03151db9ead2b56d4 Mon Sep 17 00:00:00 2001 From: joaopedroazul Date: Mon, 13 Sep 2021 19:20:45 -0300 Subject: [PATCH 12/19] :bug: Fix-Bug: Corrigindo o bug na model role again --- app/models/role.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/role.rb b/app/models/role.rb index fe3ac61..fe16c6f 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -10,6 +10,5 @@ class Role < ApplicationRecord validates :name, presence: true validates :team, presence: true - validates :leader, presence: true end From 65e959be252139b10b39ffa58d259d1288fbc445 Mon Sep 17 00:00:00 2001 From: Valentin Date: Wed, 15 Sep 2021 13:29:41 -0300 Subject: [PATCH 13/19] =?UTF-8?q?=E2=9C=85=20Coloca=20factories=20em=20arq?= =?UTF-8?q?uivos=20individuais?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/factories.rb | 24 ------------------------ spec/factories/member.rb | 6 ++++++ spec/factories/role.rb | 6 ++++++ spec/factories/team.rb | 6 ++++++ spec/factories/user.rb | 16 ++++++++++++++++ 5 files changed, 34 insertions(+), 24 deletions(-) delete mode 100644 spec/factories.rb create mode 100644 spec/factories/member.rb create mode 100644 spec/factories/role.rb create mode 100644 spec/factories/team.rb create mode 100644 spec/factories/user.rb diff --git a/spec/factories.rb b/spec/factories.rb deleted file mode 100644 index ec320ef..0000000 --- a/spec/factories.rb +++ /dev/null @@ -1,24 +0,0 @@ -FactoryBot.define do - - factory :member do - name { "Neiralay" } - roles { [] } - end - - factory :user do - name { "Neiralay" } - email { "neiralay@gmail.com" } - password { "popao123" } - password_confirmation { "popao123" } - end - - factory :team do - name { "Núcleo de Talentos" } - initials { "NUT" } - end - - factory :role do - name { "Consultor de Talentos"} - team - end -end \ No newline at end of file diff --git a/spec/factories/member.rb b/spec/factories/member.rb new file mode 100644 index 0000000..8430ce7 --- /dev/null +++ b/spec/factories/member.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :member do + name { "Neiralay" } + roles { [] } + end +end \ No newline at end of file diff --git a/spec/factories/role.rb b/spec/factories/role.rb new file mode 100644 index 0000000..75a4917 --- /dev/null +++ b/spec/factories/role.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :role do + name { "Consultor de Talentos"} + team + end +end \ No newline at end of file diff --git a/spec/factories/team.rb b/spec/factories/team.rb new file mode 100644 index 0000000..b641800 --- /dev/null +++ b/spec/factories/team.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :team do + name { "Núcleo de Talentos" } + initials { "NUT" } + end +end \ No newline at end of file diff --git a/spec/factories/user.rb b/spec/factories/user.rb new file mode 100644 index 0000000..fa6bbf7 --- /dev/null +++ b/spec/factories/user.rb @@ -0,0 +1,16 @@ +FactoryBot.define do + factory :user do + name { "Neiralay" } + email { "neiralay@gmail.com" } + password { "popao123" } + password_confirmation { "popao123" } + end + + factory :admin, class: User do + name {"Alice"} + email {"alcebories@cjr.org.br"} + password { "123popao" } + password_confirmation { "123popao" } + admin { true } + end +end \ No newline at end of file From eb4ecd96ee66ed27875b23c371a36af6e0aeffa6 Mon Sep 17 00:00:00 2001 From: Valentin Date: Wed, 15 Sep 2021 13:30:23 -0300 Subject: [PATCH 14/19] =?UTF-8?q?=E2=9C=85=20Refatora=C3=A7=C3=A3o=20dos?= =?UTF-8?q?=20testes=20do=20controller=20de=20Members?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/requests/members_spec.rb | 110 +++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 27 deletions(-) diff --git a/spec/requests/members_spec.rb b/spec/requests/members_spec.rb index cbe5e10..4eddda8 100644 --- a/spec/requests/members_spec.rb +++ b/spec/requests/members_spec.rb @@ -1,39 +1,95 @@ require "rails_helper" RSpec.describe "MembersController", :type => :request do - - let(:team) { create(:team)} - let(:role) { create(:role) } - - let(:team2) { create(:team, name: "Núcleo de Atendimento e Vendas", initials: "NAV")} - let(:role2) {create(:role, name: "Líder de Atendimento e Vendas", team: team2)} - let(:member) { create(:member, name: "Larissa Santana de Freitas Andrade", roles: [role2])} - - it "creates a Member" do - headers = { "ACCEPT" => "application/json" } - new_member = { :name => "Valentin Ferreira Paes" } - post "/members", :params => { :member => new_member }, :headers => headers - body = JSON.parse(response.body) + + before(:all) { @members_path = "/members"} + + # GET /members + describe "#index" do + before(:context) do + get @members_path + end - expect(response.content_type).to match(/application\/json/) - expect(response).to have_http_status(:created) - expect(body['name']).to eq(new_member[:name]) + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns HTTP status 200 (OK)" do + expect(response).to have_http_status(:ok) + end + end + end + + # POST /members + describe "#create" do + before(:context) do + @headers = { "ACCEPT" => "application/json" } + @new_member = { :name => "Valentin Ferreira Paes" } + post @members_path, :params => { :member => @new_member }, :headers => @headers + @body = JSON.parse(response.body) + end + + after(:context) do + Member.find_by(name: @new_member[:name]).destroy + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns HTTP status 201 (Created)" do + expect(response).to have_http_status(:created) + end + + it "returns a Member matching the params given" do + expect(@body['name']).to eq(@new_member[:name]) + end + + it "creates a new Member" do + expect{ + post @members_path, :params => { :member => { :name => "Dapedo"}}, :headers => @headers + }.to change(Member, :count).by(1) + end + end end - it "shows all Members information" do - get "/members" + context "existing single Member actions" do + before(:context) do + @role = create(:role) + @team = @role.team + @member = create(:member, roles: [@role]) + end - expect(response.content_type).to match(/application\/json/) - expect(response).to have_http_status(:ok) - end + after(:context) do + MemberRole.delete_all + Role.delete_all + Team.delete_all + Member.delete_all + end + + # GET /members/:id + describe "#show" do + before(:context) do + get (@members_path + "/#{@member.id}") + @body = JSON.parse(response.body) + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end - it "shows a Member's information" do - get "/members/#{member.id}" - body = JSON.parse(response.body) + it "returns a HTTP status 200 (OK)" do + expect(response).to have_http_status(:ok) + end - expect(response.content_type).to match(/application\/json/) - expect(response).to have_http_status(:ok) - expect(body['name']).to eq(member.name) + it "returns a JSON matching the member's attributes" do + expect(@body['name']).to eq(@member.name) + end + end + end end # it "updates a Member info" do From 48f38ba0aa80e8a8c1f41891fe566449779a1bec Mon Sep 17 00:00:00 2001 From: Valentin Date: Wed, 15 Sep 2021 13:49:38 -0300 Subject: [PATCH 15/19] =?UTF-8?q?=E2=9C=85=20Teste=20de=20requisi=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20criar=20membro=20com=20um=20cargo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/requests/members_spec.rb | 100 +++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/spec/requests/members_spec.rb b/spec/requests/members_spec.rb index 4eddda8..88af6be 100644 --- a/spec/requests/members_spec.rb +++ b/spec/requests/members_spec.rb @@ -2,7 +2,16 @@ RSpec.describe "MembersController", :type => :request do - before(:all) { @members_path = "/members"} + before(:all) { + @members_path = "/members" + @role = create(:role) + @team = @role.team + } + + after(:all){ + @role.hard_destroy + @team.hard_destroy + } # GET /members describe "#index" do @@ -23,50 +32,87 @@ # POST /members describe "#create" do - before(:context) do + before(:all){ + @previous_count = Member.count @headers = { "ACCEPT" => "application/json" } @new_member = { :name => "Valentin Ferreira Paes" } - post @members_path, :params => { :member => @new_member }, :headers => @headers - @body = JSON.parse(response.body) - end + } - after(:context) do - Member.find_by(name: @new_member[:name]).destroy - end + context "without a role" do + before(:context) do + post @members_path, :params => { :member => @new_member }, :headers => @headers + @body = JSON.parse(response.body) + end - describe "response" do - it "returns a JSON" do - expect(response.content_type).to match(/application\/json/) + after(:context) do + Member.find_by(name: @new_member[:name]).destroy end - it "returns HTTP status 201 (Created)" do - expect(response).to have_http_status(:created) - end - - it "returns a Member matching the params given" do - expect(@body['name']).to eq(@new_member[:name]) + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns HTTP status 201 (Created)" do + expect(response).to have_http_status(:created) + end + + it "returns a member with their matching the name given" do + expect(@body['name']).to eq(@new_member[:name]) + end + + it "creates a new member" do + expect(Member.count).to eq(@previous_count + 1) + end end + end + + context "with a role" do + context "the role is valid" do + before(:context) do + post @members_path, :params => { :member => @new_member, :join_roles => [@role.id] }, :headers => @headers + @body = JSON.parse(response.body) + end + + after(:context) do + Member.find_by(name: @new_member[:name]).destroy + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns HTTP status 201 (Created)" do + expect(response).to have_http_status(:created) + end + + it "returns a member with their name matching the name given" do + expect(@body['name']).to eq(@new_member[:name]) + end + + it "returns a member with a role matching the role given" do + expect(@body['roles'].last['id']).to eq(@role.id) + end + + it "creates a new Member" do + expect(Member.count).to eq(@previous_count + 1) + end + end + end - it "creates a new Member" do - expect{ - post @members_path, :params => { :member => { :name => "Dapedo"}}, :headers => @headers - }.to change(Member, :count).by(1) + context "the role is not valid" do end end end context "existing single Member actions" do before(:context) do - @role = create(:role) - @team = @role.team @member = create(:member, roles: [@role]) end after(:context) do - MemberRole.delete_all - Role.delete_all - Team.delete_all - Member.delete_all + @member.hard_destroy end # GET /members/:id From 86616eb41bff3c4796d79d7a669e13cae23550d9 Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 21 Sep 2021 13:43:47 -0300 Subject: [PATCH 16/19] =?UTF-8?q?=F0=9F=A9=B9=20Adiciona=20depend=C3=AAnci?= =?UTF-8?q?a=20de=20member=5Froles=20na=20model=20Role?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/role.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/role.rb b/app/models/role.rb index fe16c6f..ee2e69e 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,5 +1,5 @@ class Role < ApplicationRecord - has_many :member_roles + has_many :member_roles, dependent: :destroy has_many :members, through: :member_roles belongs_to :team From e43ed6976fc1c19e0a9647592a722b3136fbb4ad Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 21 Sep 2021 13:44:43 -0300 Subject: [PATCH 17/19] =?UTF-8?q?=E2=9C=85=20MembersController:=20testes?= =?UTF-8?q?=20de=20#update=20adicionando=20e=20removendo=20cargos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/requests/members_spec.rb | 71 ++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/spec/requests/members_spec.rb b/spec/requests/members_spec.rb index 88af6be..4446d4d 100644 --- a/spec/requests/members_spec.rb +++ b/spec/requests/members_spec.rb @@ -109,6 +109,7 @@ context "existing single Member actions" do before(:context) do @member = create(:member, roles: [@role]) + @member_path = @members_path + "/#{@member.id}" end after(:context) do @@ -118,7 +119,7 @@ # GET /members/:id describe "#show" do before(:context) do - get (@members_path + "/#{@member.id}") + get (@member_path) @body = JSON.parse(response.body) end @@ -136,6 +137,68 @@ end end end + + # PATCH/PUT /members/:id + describe "#update" do + describe "add single role" do + before(:context) do + token = login_admin + @new_role = create(:role, team: create(:team, name: "Equipe CGR"), name: "Dev") + put @member_path, :params => {:join_roles => [@new_role.id]}, :headers => {"Authorization" => token} + @body = JSON.parse(response.body) + end + + after(:context) do + team = @new_role.team + @new_role.destroy + team.destroy + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns a HTTP status 200 (OK)" do + expect(response).to have_http_status(:ok) + end + + it "returns a member with their name matching the name given" do + expect(@body['name']).to eq(@member[:name]) + end + + it "returns a member with a role matching the role given" do + expect(@body['roles'].last['id']).to eq(@new_role.id) + end + end + end + + describe "remove single role" do + before(:context) do + token = login_admin + put @member_path, :params => { :leave_roles => [@role.id]}, :headers => {"Authorization" => token} + @body = JSON.parse(response.body) + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns a HTTP status 200 (OK)" do + expect(response).to have_http_status(:ok) + end + + it "returns a member with their name matching the name given" do + expect(@body['name']).to eq(@member[:name]) + end + + it "returns a member without a role matching the role given" do + expect(@body['roles'].pluck("id")).to_not include(@role.id) + end + end + end + end end # it "updates a Member info" do @@ -175,4 +238,10 @@ # expect(response).to have_http_status(:no_content) # end +end + +def login_admin + post '/authenticate', :params => {email: "admin@admin.com", password: "popao123"} + body = JSON.parse(response.body) + body["auth_token"] end \ No newline at end of file From 57e74cce4c3b22947b81b1ab947f8852a807559d Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 21 Sep 2021 14:03:10 -0300 Subject: [PATCH 18/19] =?UTF-8?q?=E2=9C=85=20MembersController=20-=20Casos?= =?UTF-8?q?=20de=20erro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/requests/members_spec.rb | 50 ++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/spec/requests/members_spec.rb b/spec/requests/members_spec.rb index 4446d4d..3e4b4c5 100644 --- a/spec/requests/members_spec.rb +++ b/spec/requests/members_spec.rb @@ -106,7 +106,7 @@ end end - context "existing single Member actions" do + context "existing member actions" do before(:context) do @member = create(:member, roles: [@role]) @member_path = @members_path + "/#{@member.id}" @@ -140,6 +140,54 @@ # PATCH/PUT /members/:id describe "#update" do + describe "errors" do + describe "trying to update without permission" do + # "permission" = Current user is NEITHER an admin OR current member's user + before(:context) do + @new_member = {name: "Natália"} + put @member_path, :params => {member: @new_member} + @body = JSON.parse(response.body) + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns a HTTP status 401 (Unauthorized)" do + expect(response).to have_http_status(:unauthorized) + end + + it "returns a member with their name not matching the name given" do + expect(@body['name']).to_not eq(@new_member[:name]) + end + end + end + + describe "trying to update without valid params" do + before(:context) do + token = login_admin + @new_member = {name: nil} + put @member_path, :params => {member: @new_member}, :headers => {"Authorization" => token} + @body = JSON.parse(response.body) + end + + describe "response" do + it "returns a JSON" do + expect(response.content_type).to match(/application\/json/) + end + + it "returns a HTTP status 422 (Unprocessable Entity)" do + expect(response).to have_http_status(:unprocessable_entity) + end + + it "returns a member with their name not matching the name given" do + expect(@body['name']).to_not eq(@new_member[:name]) + end + end + end + end + describe "add single role" do before(:context) do token = login_admin From 3efc12222a0a358a2293c6b444679b914f3d2ce2 Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 21 Sep 2021 18:43:16 -0300 Subject: [PATCH 19/19] =?UTF-8?q?=E2=9C=85=20MembersController:=20Esbo?= =?UTF-8?q?=C3=A7a=20os=20testes=20restantes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/requests/members_spec.rb | 102 +++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/spec/requests/members_spec.rb b/spec/requests/members_spec.rb index 3e4b4c5..68361b6 100644 --- a/spec/requests/members_spec.rb +++ b/spec/requests/members_spec.rb @@ -141,7 +141,7 @@ # PATCH/PUT /members/:id describe "#update" do describe "errors" do - describe "trying to update without permission" do + context "trying to update without permission" do # "permission" = Current user is NEITHER an admin OR current member's user before(:context) do @new_member = {name: "Natália"} @@ -164,7 +164,7 @@ end end - describe "trying to update without valid params" do + context "trying to update without valid params" do before(:context) do token = login_admin @new_member = {name: nil} @@ -186,9 +186,16 @@ end end end + + context "trying to update a member that it not accessible (soft delete / does not exist)" do + describe "response" do + it "returns a JSON (?)" #verificar o que retorna nesse caso + it "returns a HTTP status 404 (Not Found)" + end + end end - describe "add single role" do + context "add a single role" do before(:context) do token = login_admin @new_role = create(:role, team: create(:team, name: "Equipe CGR"), name: "Dev") @@ -198,8 +205,8 @@ after(:context) do team = @new_role.team - @new_role.destroy - team.destroy + @new_role.hard_destroy + team.hard_destroy end describe "response" do @@ -211,7 +218,7 @@ expect(response).to have_http_status(:ok) end - it "returns a member with their name matching the name given" do + it "returns a member with their name matching the given member's name" do expect(@body['name']).to eq(@member[:name]) end @@ -221,7 +228,7 @@ end end - describe "remove single role" do + context "remove a single role" do before(:context) do token = login_admin put @member_path, :params => { :leave_roles => [@role.id]}, :headers => {"Authorization" => token} @@ -237,7 +244,7 @@ expect(response).to have_http_status(:ok) end - it "returns a member with their name matching the name given" do + it "returns a member with their name matching the given member's name'" do expect(@body['name']).to eq(@member[:name]) end @@ -246,46 +253,49 @@ end end end + + context "change attributes" do + describe "response" do + it "returns a JSON" + it "returns a HTTP status 200 (OK)" + it "returns a member with their name matching the name given" + end + end end - end - # it "updates a Member info" do - # headers = { "ACCEPT" => "application/json" } - # put "/members/#{larissa.id}", :params => { :member => {:name => "Larissinha lindinha"} }, :headers => headers - # body = JSON.parse(response.body) - - # expect(response.content_type).to match(/application\/json/) - # expect(response).to have_http_status(:ok) - # expect(body['name']).to eq("Larissinha lindinha") - # end - - # it "makes a Member join a role" do - # headers = { "ACCEPT" => "application/json" } - # new_role = Role.create!({:name => "Consultora de Atendimento e Vendas", :team => bope}) - # put "/members/#{larissa.id}", :params => { :member => {:id => larissa.id}, :role_id => new_role.id}, :headers => headers - # body = JSON.parse(response.body) - - # expect(response.content_type).to match(/application\/json/) - # expect(response).to have_http_status(:ok) - # expect(body['roles'][-1]['name']).to eq(new_role.name) - # end - - # it "makes a Member leave a role" do - # headers = { "ACCEPT" => "application/json" } - # put "/members/#{larissa.id}", :params => { :member => {:id => larissa.id}, :role_id => lider.id, :leave_role => true}, :headers => headers - # body = JSON.parse(response.body) - - # expect(response.content_type).to match(/application\/json/) - # expect(response).to have_http_status(:ok) - # expect(body['roles'][-1]).to eq(nil) - # end - - # it "deletes a Member" do - # headers = { "ACCEPT" => "application/json" } - # delete "/members/#{larissa.id}", :headers => headers - - # expect(response).to have_http_status(:no_content) - # end + describe "#delete" do + describe "errors" do + context "trying to delete without permission" do + end + + context "trying to soft delete a member that it not accessible (soft delete / does not exist)" do + describe "response" do + it "returns a JSON (?)" #verificar o que retorna nesse caso + it "returns a HTTP status 404 (Not Found)" + end + end + + context "trying to hard delete without beeing logged in as an admin" do + it "returns a JSON (?)" #verificar o que retorna nesse caso + it "returns a HTTP status 401 (Unauthorized)" + end + end + context "soft delete" do + describe "response" do + it "returns a JSON (?)" #verificar o que retorna nesse caso + it "returns a HTTP status 200 (OK)" + it "fills the member's field 'deleted_at'" #verificar se o campo deleted_at não está nulo + end + end + context "hard delete" do + describe "response" do + it "returns a JSON (?)" #verificar o que retorna nesse caso + it "returns a HTTP status 200 (OK)" + it "removes the member from the database" #verificar se o membro foi removido do banco + end + end + end + end end def login_admin