diff --git a/README.md b/README.md index 24fa621..70ed118 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,13 @@ API do sistema CGR da CJR. * [Especificações](#especificações) * [CI/CD](#ci-cd) * [Entidades](#entidades) + * [User](#user) * [Member](#member) * [Team](#ream) * [Role](#role) * [MemberRole](#memberrole) + * [Payment](#payment) + * [Project](#project) * [Requisições](#requisições) @@ -39,6 +42,19 @@ em um terminal bash ou zsh. Atualmente, a API conta com as seguintes entidades: +#### User + +Um usuario cadastrado no sistema pode acessar os dados referente as equipes, no qaul ele esta alocado, e a sua política de benefícios no sistema. Caso o usuario seja um admin pode criar novas equipe e projetos, além de alocar membros nos projetos e núcleos da empresa. + +| value | type | +|:-------------:|:-------------:| +| id | integer | +| name | string | +| email | string | +| admin | boolean | +| deleted_at | date_time | + + #### Member Um membro da empresa que será cadastrado no sistema. @@ -83,6 +99,30 @@ Relação entre um membro e um cargo (e, por extensão, um time). Essas relaçõ | entry_date | date_time | | deleted_at | date_time | +#### Payment + +Um pagamento será registrado no sistema toda vez que confirmar o pagamento de parcela, seja ela única ou mensal, mantendo assim um registro para realizar as funcionalidades do sistema. + +| value | type | +|:----------: |:-----------: | +| id | integer | +| amount | integer | +| payed | boolean | +| payment_date | date | + +#### Project + +Um projeto no sistema vai armazenar alguns dados importante para a empresa como: nome do projeto, descrição, extrato dos pagamento já realizados e equipe responsavel pelo projeto. + +| value | type | +|:----------: |:-----------: | +| id | integer | +| team_id | foreign_key | +| payment_id | foreign_key | +| name | string | +| client_info | string | +| project_info | string | +| deleted_at | date_time | ## Requisições @@ -221,4 +261,93 @@ Atualiza as informações de um cargo, com base em seu `id`. Pode restaurar o ca Atualiza o valor de `deleted_at` para o momento da requisição. + +#### Project +```http + GET /projects/ + GET /projects/:id + POST /projects/ + PATCH/PUT /projects/:id + DELETE /projects/:id +``` + +##### GET /projects/ + +Retorna todos os projetos não apagados do sistema + +* **content_type**: application/json +* **response**: project[]{ team } + +##### GET /projects/:id + +Retorna um projeto e a equipe responsavel com base em seu `id`, caso não esteja apagado + +* **content_type**: application/json +* **response**: project[]{ team } + +##### POST /projects/ + +Cria um projeto com um time específico no sistema. + +* **body**: team_id, payment_id(opt), name, client_info, project_info +* **content_type**: application/json +* **response**: project + +##### PATCH/PUT /projects/:id + +Atualiza as informações de um projeto, com base em seu `id`. Pode restaurar o cargo caso tenha sido apagado. + +* **body**: team_id, payment_id(opt), name, client_info, project_info, deleted_at +* **content_type**: application/json +* **response**: project + +##### DELETE /projects/:id + +Atualiza o valor de `deleted_at` para o momento da requisição. + + +#### Payments +```http + GET /payments/ + GET /payments/:id + POST /payments/ + PATCH/PUT /payments/:id + DELETE /payments/:id +``` + +##### GET /payments/ + +Retorna todos os pagamentos não apagados do sistema + +* **content_type**: application/json +* **response**: payments[] + +##### GET /payments/:id + +Retorna um pagamento com base em seu `id`, caso não esteja apagado + +* **content_type**: application/json +* **response**: payment[] + +##### POST /payments/ + +Adiciona um pagamento no sistema. + +* **body**: amount, payed, payment_date +* **content_type**: application/json +* **response**: payment + +##### PATCH/PUT /payments/:id + +Atualiza as informações de um pagamento, com base em seu `id`. Pode restaurar o cargo caso tenha sido apagado. + +* **body**: amount, payed, payment_date +* **content_type**: application/json +* **response**: payment + +##### DELETE /payments/:id + +Atualiza o valor de `deleted_at` para o momento da requisição. + + * **response**: nil \ No newline at end of file diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb new file mode 100644 index 0000000..b9dc7e8 --- /dev/null +++ b/app/controllers/payments_controller.rb @@ -0,0 +1,53 @@ +class PaymentsController < ApplicationController + before_action :set_payment, only: %i[ show update destroy ] + + # GET /payments + # GET /payments.json + def index + @payments = Payment.all + end + + # GET /payments/1 + # GET /payments/1.json + def show + end + + # POST /payments + # POST /payments.json + def create + @payment = Payment.new(payment_params) + + if @payment.save + render :show, status: :created, location: @payment + else + render json: @payment.errors, status: :unprocessable_entity + end + end + + # PATCH/PUT /payments/1 + # PATCH/PUT /payments/1.json + def update + if @payment.update(payment_params) + render :show, status: :ok, location: @payment + else + render json: @payment.errors, status: :unprocessable_entity + end + end + + # DELETE /payments/1 + # DELETE /payments/1.json + def destroy + @payment.destroy + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_payment + @payment = Payment.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def payment_params + params.require(:payment).permit(:amount, :payed, :payment_date) + end +end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb new file mode 100644 index 0000000..69b826a --- /dev/null +++ b/app/controllers/projects_controller.rb @@ -0,0 +1,51 @@ +class ProjectsController < ApplicationController + before_action :set_project, only: %i[ show update destroy ] + + # GET /projects + def index + @projects = Project.all + + render json: @projects, include: [:team] + end + + # GET /projects/1 + def show + render json: @project, include: [:team] + end + + # POST /projects + def create + @project = Project.new(project_params) + + if @project.save + render :show, status: :created, location: @project + else + render json: @project.errors, status: :unprocessable_entity + end + end + + # PATCH/PUT /projects/1 + def update + if @project.update(project_params) + render :show, status: :ok, location: @project + else + render json: @project.errors, status: :unprocessable_entity + end + end + + # DELETE /projects/1 + def destroy + @project.destroy + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_project + @project = Project.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def project_params + params.require(:project).permit(:team_id, :payment_id, :name, :client_info, :project_info, :deleted_at) + end +end diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index e0414a6..774e593 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -55,6 +55,6 @@ def set_team # Only allow a trusted parameter "white list" through. def role_params - params.require(:role).permit(:name, :team_id) + params.require(:role).permit(:name, :team_id, :description) end end diff --git a/app/controllers/teams_controller.rb b/app/controllers/teams_controller.rb index cd0d0e3..bb59ef9 100644 --- a/app/controllers/teams_controller.rb +++ b/app/controllers/teams_controller.rb @@ -1,5 +1,5 @@ class TeamsController < ApplicationController - before_action :set_team, only: [:show, :update, :destroy] + before_action :set_team, only: [:show, :show_members, :update, :destroy] include TeamManager @@ -7,12 +7,12 @@ class TeamsController < ApplicationController def index @teams = Team.all - render json: @teams, include: [:roles] + render json: @teams, include: [:roles, :members] end # GET /teams/1 def show - render json: @team, include: [:roles] + render json: @team, include: [:roles, :members] end # POST /teams @@ -52,7 +52,7 @@ def set_team # Only allow a trusted parameter "white list" through. def team_params - params.require(:team).permit(:name, :initials) + params.require(:team).permit(:name, :initials, :description) end def roles_params diff --git a/app/models/payment.rb b/app/models/payment.rb new file mode 100644 index 0000000..88223ab --- /dev/null +++ b/app/models/payment.rb @@ -0,0 +1,4 @@ +class Payment < ApplicationRecord + belongs_to :project , optional: true + +end diff --git a/app/models/project.rb b/app/models/project.rb new file mode 100644 index 0000000..c73e6e1 --- /dev/null +++ b/app/models/project.rb @@ -0,0 +1,4 @@ +class Project < ApplicationRecord + belongs_to :team + has_many :payments +end diff --git a/app/models/team.rb b/app/models/team.rb index 048dd94..312e564 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -4,10 +4,18 @@ class Team < ApplicationRecord belongs_to :parent, class_name: 'Team', optional: true has_many :children, class_name: 'Team', foreign_key: 'parent_id' - + belongs_to :project , optional: true include SoftDeletable validates :name, uniqueness: true, presence: true + + def members + members = [] + self.roles.all.each do |role| + members = members + role.members.all + end + members + end # Validar se apenas um cargo (ou nenhum) tem a flag de 'leader' # Dica: Usar método 'validate' como: # diff --git a/app/views/payments/_payment.json.jbuilder b/app/views/payments/_payment.json.jbuilder new file mode 100644 index 0000000..9d62b51 --- /dev/null +++ b/app/views/payments/_payment.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! payment, :id, :amount, :payed, :payment_date, :created_at, :updated_at +json.url payment_url(payment, format: :json) diff --git a/app/views/payments/index.json.jbuilder b/app/views/payments/index.json.jbuilder new file mode 100644 index 0000000..cd498bb --- /dev/null +++ b/app/views/payments/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @payments, partial: "payments/payment", as: :payment diff --git a/app/views/payments/show.json.jbuilder b/app/views/payments/show.json.jbuilder new file mode 100644 index 0000000..da088d8 --- /dev/null +++ b/app/views/payments/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "payments/payment", payment: @payment diff --git a/app/views/projects/_project.json.jbuilder b/app/views/projects/_project.json.jbuilder new file mode 100644 index 0000000..2167842 --- /dev/null +++ b/app/views/projects/_project.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! project, :id, :team_id, :payment_id, :name, :client_info, :project_info, :deleted_at, :created_at, :updated_at +json.url project_url(project, format: :json) diff --git a/app/views/projects/index.json.jbuilder b/app/views/projects/index.json.jbuilder new file mode 100644 index 0000000..e9db4f9 --- /dev/null +++ b/app/views/projects/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @projects, partial: "projects/project", as: :project diff --git a/app/views/projects/show.json.jbuilder b/app/views/projects/show.json.jbuilder new file mode 100644 index 0000000..0be99bd --- /dev/null +++ b/app/views/projects/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "projects/project", project: @project diff --git a/config/routes.rb b/config/routes.rb index 38748c4..6f93b01 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,6 @@ Rails.application.routes.draw do + resources :payments + resources :projects resources :teams, shallow: true do resources :roles end diff --git a/db/migrate/20210929143634_create_payments.rb b/db/migrate/20210929143634_create_payments.rb new file mode 100644 index 0000000..d6e4139 --- /dev/null +++ b/db/migrate/20210929143634_create_payments.rb @@ -0,0 +1,11 @@ +class CreatePayments < ActiveRecord::Migration[6.1] + def change + create_table :payments do |t| + t.integer :amount + t.boolean :payed + t.date :payment_date + + t.timestamps + end + end +end diff --git a/db/migrate/20210929143726_create_projects.rb b/db/migrate/20210929143726_create_projects.rb new file mode 100644 index 0000000..043037a --- /dev/null +++ b/db/migrate/20210929143726_create_projects.rb @@ -0,0 +1,14 @@ +class CreateProjects < ActiveRecord::Migration[6.1] + def change + create_table :projects do |t| + t.references :team, foreign_key: true + t.references :payment, foreign_key: true + t.string :name + t.string :client_info + t.string :project_info + t.datetime :deleted_at + + t.timestamps + end + end +end diff --git a/db/migrate/20211208134156_add_description_to_teams.rb b/db/migrate/20211208134156_add_description_to_teams.rb new file mode 100644 index 0000000..042f4c7 --- /dev/null +++ b/db/migrate/20211208134156_add_description_to_teams.rb @@ -0,0 +1,5 @@ +class AddDescriptionToTeams < ActiveRecord::Migration[6.1] + def change + add_column :teams, :description, :text + end +end diff --git a/db/migrate/20211208134211_add_description_to_role.rb b/db/migrate/20211208134211_add_description_to_role.rb new file mode 100644 index 0000000..1cf39ab --- /dev/null +++ b/db/migrate/20211208134211_add_description_to_role.rb @@ -0,0 +1,5 @@ +class AddDescriptionToRole < ActiveRecord::Migration[6.1] + def change + add_column :roles, :description, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index 69b6429..cba2250 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: 2021_09_13_205929) do +ActiveRecord::Schema.define(version: 2021_12_08_134211) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -35,24 +35,47 @@ t.index ["user_id"], name: "index_members_on_user_id" end + create_table "payments", force: :cascade do |t| + t.integer "amount" + t.boolean "payed" + t.date "payment_date" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + + create_table "projects", force: :cascade do |t| + t.bigint "team_id" + t.bigint "payment_id" + t.string "name" + t.string "client_info" + t.string "project_info" + t.datetime "deleted_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["payment_id"], name: "index_projects_on_payment_id" + t.index ["team_id"], name: "index_projects_on_team_id" + 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.boolean "leader" - t.index ["parent_id"], name: "index_roles_on_parent_id" + t.text "description" t.index ["team_id"], name: "index_roles_on_team_id" end create_table "teams", force: :cascade do |t| + t.bigint "parent_id" t.string "name" t.string "initials" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.datetime "deleted_at" + t.text "description" + t.index ["parent_id"], name: "index_teams_on_parent_id" end create_table "users", force: :cascade do |t| @@ -67,6 +90,8 @@ 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 "projects", "payments" + add_foreign_key "projects", "teams" add_foreign_key "roles", "teams" + add_foreign_key "teams", "teams", column: "parent_id" end diff --git a/db/seeds.rb b/db/seeds.rb index 899a164..0753712 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -14,4 +14,93 @@ membro = Role.find_or_create_by!({ name: 'Membro', team: equipe}) cabral = Member.find_or_create_by!({ name: 'João Victor Cabral de Melo'}) -MemberRole.find_or_create_by!({member: cabral, role: membro, entry_date: DateTime.now}) \ No newline at end of file +MemberRole.find_or_create_by!({member: cabral, role: membro, entry_date: DateTime.now}) + +# Users basics +User.create!({name: 'Azul', + email: 'azul@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: true}) + +User.create!({name: 'Dapedu', + email: 'dapedu@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: true}) + +User.create!({name: 'Alice', + email: 'alice@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: false}) + +User.create!({name: 'Neiralay', + email: 'neiralay@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: false}) + +User.create!({name: 'Thisgo', + email: 'thisgo@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: true}) + +User.create!({name: 'Sorriso', + email: 'sorriso@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: true}) + +User.create!({name: 'Gustavo', + email: 'gustavo@noe.com', + password: 'popao123', + password_confirmation: 'popao123', + admin: false}) + +#Teams for tests +cgr = Team.find_or_create_by!({ name: 'Equipe CGR'}) +ilcaffe = Team.find_or_create_by!({ name: 'Equipe ilcaffe'}) + +#test roles +devCgr = Role.find_or_create_by!({ name: 'Dev', team: cgr}) +gerenteCgr = Role.find_or_create_by!({ name: 'Gerente', team: cgr}) +negociadorCgr = Role.find_or_create_by!({ name: 'Negociador', team: cgr}) + +devIlcaffe = Role.find_or_create_by!({ name: 'Dev', team: ilcaffe}) +gerenteIlcaffe = Role.find_or_create_by!({ name: 'Gerente', team: ilcaffe}) +negociadorIlcaffe = Role.find_or_create_by!({ name: 'Negociador', team: ilcaffe}) + +#test members + +dapedu = Member.find_or_create_by!({ name: 'Dapedu'}) +MemberRole.find_or_create_by!({member: dapedu, role: gerenteCgr, entry_date: DateTime.now}) + +azul = Member.find_or_create_by!({ name: 'Azul'}) +MemberRole.find_or_create_by!({member: azul, role: devCgr, entry_date: DateTime.now}) + +sorriso = Member.find_or_create_by!({ name: 'Sorriso'}) +MemberRole.find_or_create_by!({member: sorriso, role: devCgr, entry_date: DateTime.now}) + +thisgo = Member.find_or_create_by!({ name: 'Thisgo'}) +MemberRole.find_or_create_by!({member: thisgo, role: devCgr, entry_date: DateTime.now}) + +alice = Member.find_or_create_by!({ name: 'Alice'}) +MemberRole.find_or_create_by!({member: alice, role: gerenteIlcaffe, entry_date: DateTime.now}) + +neiralay = Member.find_or_create_by!({ name: 'Neiralay'}) +MemberRole.find_or_create_by!({member: neiralay, role: devIlcaffe, entry_date: DateTime.now}) + +gustavo = Member.find_or_create_by!({ name: 'Gustavo'}) +MemberRole.find_or_create_by!({member: gustavo, role: devIlcaffe, entry_date: DateTime.now}) + +#tests payment +cash = Payment.find_or_create_by!({ amount: 3000, payed:true, payment_date:''}) +cash2 = Payment.find_or_create_by!({ amount: 1500, payed:false, payment_date:''}) + +#tests projects +nameProject = Team.find_by_name("Equipe CGR").id +Project.find_or_create_by!({ team_id: nameProject ,name:'CGR',client_info:'',project_info:''}) +nameProject2 = Team.find_by_name('Equipe ilcaffe').id +Project.find_or_create_by!({ team_id: nameProject2, payment_id: cash,name:'IlCaffé',client_info:'',project_info:''}) diff --git a/spec/factories/payments.rb b/spec/factories/payments.rb new file mode 100644 index 0000000..cbb74f0 --- /dev/null +++ b/spec/factories/payments.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :payment do + amount { "" } + payed { false } + payment_date { "2021-09-29" } + end +end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb new file mode 100644 index 0000000..eaf55b4 --- /dev/null +++ b/spec/factories/projects.rb @@ -0,0 +1,10 @@ +FactoryBot.define do + factory :project do + team_id { nil } + payment_id { nil } + name { "MyString" } + client_info { "MyString" } + project_info { "MyString" } + deleted_at { "2021-09-29 11:35:26" } + end +end diff --git a/spec/models/payment_spec.rb b/spec/models/payment_spec.rb new file mode 100644 index 0000000..c185224 --- /dev/null +++ b/spec/models/payment_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Payment, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb new file mode 100644 index 0000000..99ad389 --- /dev/null +++ b/spec/models/project_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Project, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/payments_spec.rb b/spec/requests/payments_spec.rb new file mode 100644 index 0000000..299cfe9 --- /dev/null +++ b/spec/requests/payments_spec.rb @@ -0,0 +1,127 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to test 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. + +RSpec.describe "/payments", type: :request do + # This should return the minimal set of attributes required to create a valid + # Payment. As you add validations to Payment, 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 headers + # in order to pass any filters (e.g. authentication) defined in + # PaymentsController, or in your router and rack + # middleware. Be sure to keep this updated too. + let(:valid_headers) { + {} + } + + describe "GET /index" do + it "renders a successful response" do + Payment.create! valid_attributes + get payments_url, headers: valid_headers, as: :json + expect(response).to be_successful + end + end + + describe "GET /show" do + it "renders a successful response" do + payment = Payment.create! valid_attributes + get payment_url(payment), as: :json + expect(response).to be_successful + end + end + + describe "POST /create" do + context "with valid parameters" do + it "creates a new Payment" do + expect { + post payments_url, + params: { payment: valid_attributes }, headers: valid_headers, as: :json + }.to change(Payment, :count).by(1) + end + + it "renders a JSON response with the new payment" do + post payments_url, + params: { payment: valid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:created) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "does not create a new Payment" do + expect { + post payments_url, + params: { payment: invalid_attributes }, as: :json + }.to change(Payment, :count).by(0) + end + + it "renders a JSON response with errors for the new payment" do + post payments_url, + params: { payment: invalid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to eq("application/json") + end + end + end + + describe "PATCH /update" do + context "with valid parameters" do + let(:new_attributes) { + skip("Add a hash of attributes valid for your model") + } + + it "updates the requested payment" do + payment = Payment.create! valid_attributes + patch payment_url(payment), + params: { payment: new_attributes }, headers: valid_headers, as: :json + payment.reload + skip("Add assertions for updated state") + end + + it "renders a JSON response with the payment" do + payment = Payment.create! valid_attributes + patch payment_url(payment), + params: { payment: new_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:ok) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "renders a JSON response with errors for the payment" do + payment = Payment.create! valid_attributes + patch payment_url(payment), + params: { payment: invalid_attributes }, headers: valid_headers, as: :json + 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 payment" do + payment = Payment.create! valid_attributes + expect { + delete payment_url(payment), headers: valid_headers, as: :json + }.to change(Payment, :count).by(-1) + end + end +end diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb new file mode 100644 index 0000000..35bbd56 --- /dev/null +++ b/spec/requests/projects_spec.rb @@ -0,0 +1,127 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to test 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. + +RSpec.describe "/projects", type: :request do + # This should return the minimal set of attributes required to create a valid + # Project. As you add validations to Project, 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 headers + # in order to pass any filters (e.g. authentication) defined in + # ProjectsController, or in your router and rack + # middleware. Be sure to keep this updated too. + let(:valid_headers) { + {} + } + + describe "GET /index" do + it "renders a successful response" do + Project.create! valid_attributes + get projects_url, headers: valid_headers, as: :json + expect(response).to be_successful + end + end + + describe "GET /show" do + it "renders a successful response" do + project = Project.create! valid_attributes + get project_url(project), as: :json + expect(response).to be_successful + end + end + + describe "POST /create" do + context "with valid parameters" do + it "creates a new Project" do + expect { + post projects_url, + params: { project: valid_attributes }, headers: valid_headers, as: :json + }.to change(Project, :count).by(1) + end + + it "renders a JSON response with the new project" do + post projects_url, + params: { project: valid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:created) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "does not create a new Project" do + expect { + post projects_url, + params: { project: invalid_attributes }, as: :json + }.to change(Project, :count).by(0) + end + + it "renders a JSON response with errors for the new project" do + post projects_url, + params: { project: invalid_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to eq("application/json") + end + end + end + + describe "PATCH /update" do + context "with valid parameters" do + let(:new_attributes) { + skip("Add a hash of attributes valid for your model") + } + + it "updates the requested project" do + project = Project.create! valid_attributes + patch project_url(project), + params: { project: new_attributes }, headers: valid_headers, as: :json + project.reload + skip("Add assertions for updated state") + end + + it "renders a JSON response with the project" do + project = Project.create! valid_attributes + patch project_url(project), + params: { project: new_attributes }, headers: valid_headers, as: :json + expect(response).to have_http_status(:ok) + expect(response.content_type).to match(a_string_including("application/json")) + end + end + + context "with invalid parameters" do + it "renders a JSON response with errors for the project" do + project = Project.create! valid_attributes + patch project_url(project), + params: { project: invalid_attributes }, headers: valid_headers, as: :json + 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 project" do + project = Project.create! valid_attributes + expect { + delete project_url(project), headers: valid_headers, as: :json + }.to change(Project, :count).by(-1) + end + end +end diff --git a/spec/routing/payments_routing_spec.rb b/spec/routing/payments_routing_spec.rb new file mode 100644 index 0000000..fbbce62 --- /dev/null +++ b/spec/routing/payments_routing_spec.rb @@ -0,0 +1,30 @@ +require "rails_helper" + +RSpec.describe PaymentsController, type: :routing do + describe "routing" do + it "routes to #index" do + expect(get: "/payments").to route_to("payments#index") + end + + it "routes to #show" do + expect(get: "/payments/1").to route_to("payments#show", id: "1") + end + + + it "routes to #create" do + expect(post: "/payments").to route_to("payments#create") + end + + it "routes to #update via PUT" do + expect(put: "/payments/1").to route_to("payments#update", id: "1") + end + + it "routes to #update via PATCH" do + expect(patch: "/payments/1").to route_to("payments#update", id: "1") + end + + it "routes to #destroy" do + expect(delete: "/payments/1").to route_to("payments#destroy", id: "1") + end + end +end diff --git a/spec/routing/projects_routing_spec.rb b/spec/routing/projects_routing_spec.rb new file mode 100644 index 0000000..4cbc5d0 --- /dev/null +++ b/spec/routing/projects_routing_spec.rb @@ -0,0 +1,30 @@ +require "rails_helper" + +RSpec.describe ProjectsController, type: :routing do + describe "routing" do + it "routes to #index" do + expect(get: "/projects").to route_to("projects#index") + end + + it "routes to #show" do + expect(get: "/projects/1").to route_to("projects#show", id: "1") + end + + + it "routes to #create" do + expect(post: "/projects").to route_to("projects#create") + end + + it "routes to #update via PUT" do + expect(put: "/projects/1").to route_to("projects#update", id: "1") + end + + it "routes to #update via PATCH" do + expect(patch: "/projects/1").to route_to("projects#update", id: "1") + end + + it "routes to #destroy" do + expect(delete: "/projects/1").to route_to("projects#destroy", id: "1") + end + end +end