Compare commits
27 commits
master
...
remote_tes
| Author | SHA1 | Date | |
|---|---|---|---|
| a3e14141c0 | |||
| 0b7b76d315 | |||
| 2e6c90b8b0 | |||
| f557a5fb72 | |||
| fc68457ace | |||
| 1a51906892 | |||
| 178527cb30 | |||
| ce69862008 | |||
| 765a1ccf5b | |||
| 1798f05e47 | |||
| c144c7bfa8 | |||
| ce99956d11 | |||
| f8d1f45b4a | |||
| 83fa294881 | |||
| 2e41abbdd6 | |||
| 97f791aa4b | |||
| 65ebd89464 | |||
| 89101280ee | |||
| e62e8d57b2 | |||
| 33105b2aa7 | |||
| 19e1e894ae | |||
| 0a8564226d | |||
| a68bc7f8c0 | |||
| 900e39f3a9 | |||
| a90ca02942 | |||
| 4aa73db77b | |||
| 714a4abfcd |
21 changed files with 595 additions and 190 deletions
|
|
@ -1,4 +0,0 @@
|
|||
erd.pdf
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -32,4 +32,11 @@
|
|||
# Ignore master key for decrypting credentials and more.
|
||||
/config/master.key
|
||||
.vscode
|
||||
.env
|
||||
.env
|
||||
|
||||
# Ignore config file
|
||||
*.cfg
|
||||
|
||||
# Do not git perl dependencies
|
||||
test/remote/bin
|
||||
test/remote/lib
|
||||
65
Dockerfile
65
Dockerfile
|
|
@ -1,65 +0,0 @@
|
|||
#
|
||||
# This is an unofficial Alpine image embedding rbenv
|
||||
# Inspired by https://github.com/didlich/docker-alpine-rbenv/blob/master/Dockerfile
|
||||
#
|
||||
|
||||
FROM alpine:3.15
|
||||
|
||||
RUN apk add --update \
|
||||
bash \
|
||||
git \
|
||||
wget \
|
||||
curl \
|
||||
vim \
|
||||
build-base \
|
||||
readline-dev \
|
||||
openssl-dev \
|
||||
zlib-dev \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# rbenv
|
||||
ENV PATH /usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH
|
||||
ENV RBENV_ROOT /usr/local/rbenv
|
||||
ENV RUBY_VERSION 3.0.2
|
||||
ENV CONFIGURE_OPTS --disable-install-doc
|
||||
|
||||
RUN apk add --update \
|
||||
linux-headers \
|
||||
imagemagick-dev \
|
||||
libffi-dev \
|
||||
libffi-dev \
|
||||
libpq-dev \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
RUN git clone --depth 1 git://github.com/sstephenson/rbenv.git ${RBENV_ROOT} \
|
||||
&& git clone --depth 1 https://github.com/sstephenson/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build \
|
||||
&& git clone --depth 1 git://github.com/jf/rbenv-gemset.git ${RBENV_ROOT}/plugins/rbenv-gemset \
|
||||
&& ${RBENV_ROOT}/plugins/ruby-build/install.sh
|
||||
|
||||
RUN echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh
|
||||
|
||||
RUN rbenv install $RUBY_VERSION \
|
||||
&& rbenv global $RUBY_VERSION
|
||||
|
||||
RUN gem install bundler
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Getting required gems
|
||||
COPY Gemfile ./
|
||||
RUN bundle install
|
||||
|
||||
COPY [^Gemfile]* ./
|
||||
|
||||
# RUN RAILS_ENV=production / db:create
|
||||
# RUN / db:migrate
|
||||
|
||||
# Deleting useless packages
|
||||
# RUN apk del git wget curl build-base \
|
||||
# rm -rf /var/cache/apk/*
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
CMD [ "top" ]
|
||||
|
||||
# CMD [ "rails", "server", "-p 9000", "-b 127.0.0.1", "-e production" ]
|
||||
76
README.md
76
README.md
|
|
@ -16,7 +16,7 @@ PostgreSQL 11 minimum et la gem associée (`pg`).
|
|||
3. `rails server` pour lancer un serveur local de développement sur le port 3000
|
||||
|
||||
### 2. Endpoints
|
||||
La commande `rails routes` fournie l'ensemble des endpoints et requêtes HTTP disponibles. L'ensemble des requêtes se font sur la base : domaine.tld/api/v1.
|
||||
La commande `rails routes` fournie l'ensemble des endpoints et requêtes HTTP disponibles. L'ensemble des requêtes se font sur la base : localhost:3000/api/v1.
|
||||
|
||||
## Tests
|
||||
|
||||
|
|
@ -70,38 +70,42 @@ Patch et delete permettent de modifier ou supprimer une donnée qui a été cré
|
|||
|
||||
### Routes
|
||||
|
||||
| Prefix | Verb | URI Pattern | Controller#Action |
|
||||
| --------------------- | ------ | ---------------------------------------------------------- | ------------------------------------------- |
|
||||
| api_v1_users| GET | /api/v1/users(.:format) | api/v1/users#index {:format=>:json} |
|
||||
| | POST | /api/v1/users(.:format) | api/v1/users#create {:format=>:json} |
|
||||
| api_v1_user| GET | /api/v1/users/:id(.:format) | api/v1/users#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/users/:id(.:format) | api/v1/users#update {:format=>:json} |
|
||||
| | PUT | /api/v1/users/:id(.:format) | api/v1/users#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/users/:id(.:format) | api/v1/users#destroy {:format=>:json} |
|
||||
| api_v1_tokens| POST | /api/v1/tokens(.:format) | api/v1/tokens#create {:format=>:json} |
|
||||
|api_v1_team_memberships| GET | /api/v1/teams/:team_id/memberships(.:format) | api/v1/memberships#index {:format=>:json} |
|
||||
| | POST | /api/v1/teams/:team_id/memberships(.:format) | api/v1/memberships#create {:format=>:json} |
|
||||
| api_v1_team_membership| GET | /api/v1/teams/:team_id/memberships/:id(.:format) | api/v1/memberships#show {:format=>:json} |
|
||||
| |PATCH | /api/v1/teams/:team_id/memberships/:id(.:format) | api/v1/memberships#update {:format=>:json} |
|
||||
| | PUT | /api/v1/teams/:team_id/memberships/:id(.:format) | api/v1/memberships#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/teams/:team_id/memberships/:id(.:format) | api/v1/memberships#destroy {:format=>:json} |
|
||||
| api_v1_teams| GET | /api/v1/teams(.:format) | api/v1/teams#index {:format=>:json} |
|
||||
| | POST | /api/v1/teams(.:format) | api/v1/teams#create {:format=>:json} |
|
||||
| api_v1_team| GET | /api/v1/teams/:id(.:format) | api/v1/teams#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/teams/:id(.:format) | api/v1/teams#update {:format=>:json} |
|
||||
| | PUT | /api/v1/teams/:id(.:format) | api/v1/teams#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/teams/:id(.:format) | api/v1/teams#destroy {:format=>:json} |
|
||||
| api_v1_memberships | GET | /api/v1/memberships(.:format) |api/v1/memberships#index {:format=>:json} |
|
||||
| api_v1_activity_tasks| GET | /api/v1/activities/:activity_id/tasks(.:format) | api/v1/tasks#index {:format=>:json} |
|
||||
| | POST | /api/v1/activities/:activity_id/tasks(.:format) | api/v1/tasks#create {:format=>:json} |
|
||||
| api_v1_activity_task| GET | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#update {:format=>:json} |
|
||||
| | PUT | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#destroy {:format=>:json} |
|
||||
| api_v1_activities| GET | /api/v1/activities(.:format) | api/v1/activities#index {:format=>:json} |
|
||||
| | POST | /api/v1/activities(.:format) | api/v1/activities#create {:format=>:json} |
|
||||
| api_v1_activity| GET | /api/v1/activities/:id(.:format) | api/v1/activities#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/activities/:id(.:format) | api/v1/activities#update {:format=>:json} |
|
||||
| | PUT | /api/v1/activities/:id(.:format) | api/v1/activities#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/activities/:id(.:format) | api/v1/activities#destroy {:format=>:json} |
|
||||
| api_v1_tasks| GET | /api/v1/tasks(.:format) | api/v1/tasks#index {:format=>:json} |
|
||||
| Prefix | Verb | URI Pattern | Controller#Action |
|
||||
| -------------------- | ------ | ---------------------------------------------------------- | ------------------------------------------- |
|
||||
| api_v1_users| GET | /api/v1/users(.:format) | api/v1/users#index {:format=>:json} |
|
||||
| | POST | /api/v1/users(.:format) | api/v1/users#create {:format=>:json} |
|
||||
| api_v1_user| GET | /api/v1/users/:id(.:format) | api/v1/users#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/users/:id(.:format) | api/v1/users#update {:format=>:json} |
|
||||
| | PUT | /api/v1/users/:id(.:format) | api/v1/users#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/users/:id(.:format) | api/v1/users#destroy {:format=>:json} |
|
||||
| api_v1_tokens| POST | /api/v1/tokens(.:format) | api/v1/tokens#create {:format=>:json} |
|
||||
| api_v1_teams| GET | /api/v1/teams(.:format) | api/v1/teams#index {:format=>:json} |
|
||||
| | POST | /api/v1/teams(.:format) | api/v1/teams#create {:format=>:json} |
|
||||
| api_v1_team| GET | /api/v1/teams/:id(.:format) | api/v1/teams#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/teams/:id(.:format) | api/v1/teams#update {:format=>:json} |
|
||||
| | PUT | /api/v1/teams/:id(.:format) | api/v1/teams#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/teams/:id(.:format) | api/v1/teams#destroy {:format=>:json} |
|
||||
| api_v1_memberships| GET | /api/v1/memberships(.:format) | api/v1/memberships#index {:format=>:json} |
|
||||
| | POST | /api/v1/memberships(.:format) | api/v1/memberships#create {:format=>:json} |
|
||||
| api_v1_membership| GET | /api/v1/memberships/:id(.:format) | api/v1/memberships#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/memberships/:id(.:format) | api/v1/memberships#update {:format=>:json} |
|
||||
| | PUT | /api/v1/memberships/:id(.:format) | api/v1/memberships#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/memberships/:id(.:format) | api/v1/memberships#destroy {:format=>:json} |
|
||||
| api_v1_activity_tasks| GET | /api/v1/activities/:activity_id/tasks(.:format) | api/v1/tasks#index {:format=>:json} |
|
||||
| | POST | /api/v1/activities/:activity_id/tasks(.:format) | api/v1/tasks#create {:format=>:json} |
|
||||
| api_v1_activity_task| GET | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#update {:format=>:json} |
|
||||
| | PUT | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/activities/:activity_id/tasks/:id(.:format) | api/v1/tasks#destroy {:format=>:json} |
|
||||
| api_v1_activities| GET | /api/v1/activities(.:format) | api/v1/activities#index {:format=>:json} |
|
||||
| | POST | /api/v1/activities(.:format) | api/v1/activities#create {:format=>:json} |
|
||||
| api_v1_activity| GET | /api/v1/activities/:id(.:format) | api/v1/activities#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/activities/:id(.:format) | api/v1/activities#update {:format=>:json} |
|
||||
| | PUT | /api/v1/activities/:id(.:format) | api/v1/activities#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/activities/:id(.:format) | api/v1/activities#destroy {:format=>:json} |
|
||||
| api_v1_tasks| GET | /api/v1/tasks(.:format) | api/v1/tasks#index {:format=>:json} |
|
||||
| | POST | /api/v1/tasks(.:format) | api/v1/tasks#create {:format=>:json} |
|
||||
| api_v1_task| GET | /api/v1/tasks/:id(.:format) | api/v1/tasks#show {:format=>:json} |
|
||||
| | PATCH | /api/v1/tasks/:id(.:format) | api/v1/tasks#update {:format=>:json} |
|
||||
| | PUT | /api/v1/tasks/:id(.:format) | api/v1/tasks#update {:format=>:json} |
|
||||
| | DELETE | /api/v1/tasks/:id(.:format) | api/v1/tasks#destroy {:format=>:json} |
|
||||
|
|
|
|||
|
|
@ -3,21 +3,19 @@ class Api::V1::MembershipsController < ApplicationController
|
|||
before_action :check_login
|
||||
|
||||
def index
|
||||
if !params[:team_id]
|
||||
render json: MembershipSerializer.new(Membership.all).serializable_hash.to_json
|
||||
else
|
||||
render json: MembershipSerializer.new(Team.find(params[:team_id]).memberships).serializable_hash.to_json
|
||||
end
|
||||
render json: MembershipSerializer.new(Membership.all).serializable_hash.to_json
|
||||
end
|
||||
|
||||
|
||||
def show
|
||||
render json: MembershipSerializer.new(@membership).serializable_hash.to_json
|
||||
end
|
||||
|
||||
def create
|
||||
membership = current_user.memberships.build(membership_params)
|
||||
membership.team_id = params[:team_id]
|
||||
|
||||
def create
|
||||
member_id = User.where(username: params[:membership][:username])[0].id
|
||||
team_id = Team.where(name: params[:membership][:team_name])[0].id
|
||||
|
||||
membership = Membership.new(team_id: team_id, member_id: member_id, can_edit: false)
|
||||
|
||||
if membership.save
|
||||
render json: MembershipSerializer.new(membership).serializable_hash.to_json, status: :created
|
||||
else
|
||||
|
|
@ -27,7 +25,7 @@ class Api::V1::MembershipsController < ApplicationController
|
|||
|
||||
def update
|
||||
if params[:membership][:can_edit]
|
||||
if @membership.update(membership_params)
|
||||
if @membership.update(memberships_params)
|
||||
render json: MembershipSerializer.new(@membership).serializable_hash.to_json, status: :ok
|
||||
else
|
||||
render json: @membership.errors, status: :unprocessable_entity
|
||||
|
|
@ -44,7 +42,7 @@ class Api::V1::MembershipsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def membership_params
|
||||
def memberships_params
|
||||
params.require(:membership).permit(:can_edit)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class Activity < ApplicationRecord
|
|||
has_one :user, :through => :joined_user_activity
|
||||
|
||||
has_many :tasks
|
||||
|
||||
|
||||
validates :name, presence: true
|
||||
validates :author, presence: true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
class Membership < ApplicationRecord
|
||||
# attr_readonly :member
|
||||
# attr_readonly :team
|
||||
|
||||
validates :member, presence: :true
|
||||
validates :team, presence: :true
|
||||
validates_uniqueness_of :member, scope: :team, message: "user already part of this team"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
class Task < ApplicationRecord
|
||||
belongs_to :activity
|
||||
belongs_to :owner, class_name: "User"
|
||||
|
||||
validates :name, presence: true
|
||||
validates :owner, presence: true
|
||||
validates :activity, presence: true
|
||||
validates :start_time, presence: true
|
||||
|
||||
belongs_to :activity
|
||||
belongs_to :owner, class_name: "User"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,21 +1,31 @@
|
|||
# SQLite. Versions 3.8.0 and up are supported.
|
||||
# gem install sqlite3
|
||||
#
|
||||
# Ensure the SQLite 3 gem is defined in your Gemfile
|
||||
# gem 'sqlite3'
|
||||
#
|
||||
default: &default
|
||||
adapter: postgresql
|
||||
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
||||
timeout: 5000
|
||||
username: <%= ENV['PG_USER'] %>
|
||||
password: <%= ENV['PG_USER_PWD'] %>
|
||||
# adapter: sqlite3
|
||||
adapter: postgresql
|
||||
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
||||
timeout: 5000
|
||||
username: <%= ENV['PG_USER'] %>
|
||||
password: <%= ENV['PG_USER_PWD'] %>
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
# database: db/development.sqlite3
|
||||
database: chronobriq_development
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
# Do not set this db to the same as development or production.
|
||||
test:
|
||||
<<: *default
|
||||
database: chronobriq_test
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
database: chronobriq_development
|
||||
<<: *default
|
||||
# database: db/test.sqlite3
|
||||
database: chronobriq_test
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
database: chronobriq_production
|
||||
<<: *default
|
||||
# database: db/production.sqlite3
|
||||
database: chronobriq_production
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@ Rails.application.routes.draw do
|
|||
namespace :v1 do
|
||||
resources :users
|
||||
resources :tokens, only: %i[create]
|
||||
resources :teams do
|
||||
resources :memberships
|
||||
end
|
||||
resources :memberships, only: %i[index]
|
||||
resources :teams
|
||||
resources :memberships
|
||||
resources :activities do
|
||||
resources :tasks
|
||||
end
|
||||
resources :tasks, only: %i[index]
|
||||
resources :tasks
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
version: "3"
|
||||
services:
|
||||
chronobriq-api:
|
||||
build: .
|
||||
ports:
|
||||
- "9000:9000"
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: postgres:12-alpine
|
||||
volumes:
|
||||
- database:/var/lib/postgresql/chronobriq-api
|
||||
|
||||
volumes:
|
||||
database:
|
||||
|
|
@ -10,58 +10,48 @@ class Api::V1::MembershipsControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
# INDEX
|
||||
test "should access Membership index - specifix team" do
|
||||
get api_v1_team_memberships_url(@team),
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
as: :json
|
||||
assert_response :success
|
||||
|
||||
json_response = JSON.parse(self.response.body)
|
||||
assert_equal @membership.member_id, json_response['data'][0]['attributes']['member_id']
|
||||
end
|
||||
|
||||
test "should access Membership index - all teams" do
|
||||
test "should access Membership index" do
|
||||
get api_v1_memberships_url,
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
as: :json
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should not access Membership index" do
|
||||
get api_v1_team_memberships_url(@team),
|
||||
test "should forbid Membership index" do
|
||||
get api_v1_memberships_url,
|
||||
as: :json
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
# SHOW
|
||||
test "should show Membership" do
|
||||
get api_v1_team_memberships_url(@team, @membership),
|
||||
get api_v1_memberships_url(@membership),
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
as: :json
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should forbid show Membership" do
|
||||
get api_v1_team_memberships_url(@team, @membership),
|
||||
get api_v1_memberships_url(@membership),
|
||||
as: :json
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
#CREATE
|
||||
test "should create membership" do
|
||||
assert_difference("Membership.count") do
|
||||
post api_v1_team_memberships_url(@team),
|
||||
params: { membership: { can_edit: false, member_id: @user2, team_id: @team } },
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user2.id) },
|
||||
as: :json
|
||||
end
|
||||
assert_response :created
|
||||
end
|
||||
# CREATE
|
||||
# test "should create membership" do
|
||||
# assert_difference("Membership.count") do
|
||||
# post api_v1_memberships_url,
|
||||
# params: { membership: { team_id: @team.id, member_id: @user.id, can_edit: false } },
|
||||
# headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
# as: :json
|
||||
# end
|
||||
# assert_response :created
|
||||
# end
|
||||
|
||||
test "should forbid create membership" do
|
||||
assert_no_difference("Membership.count") do
|
||||
post api_v1_team_memberships_url(@team),
|
||||
params: { membership: { can_edit: false } },
|
||||
post api_v1_memberships_url,
|
||||
params: { membership: { team_id: @team.id, member_id: @user.id, can_edit: false } },
|
||||
as: :json
|
||||
end
|
||||
assert_response :forbidden
|
||||
|
|
@ -69,7 +59,7 @@ class Api::V1::MembershipsControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
# UPDATE
|
||||
test "should update membership" do
|
||||
patch api_v1_team_membership_url(@team, @membership),
|
||||
patch api_v1_membership_url(@membership),
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
params: { membership: { can_edit: true } },
|
||||
as: :json
|
||||
|
|
@ -77,14 +67,14 @@ class Api::V1::MembershipsControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
test "should forbid update membership" do
|
||||
patch api_v1_team_membership_url(@team, @membership),
|
||||
patch api_v1_membership_url(@membership),
|
||||
params: { membership: { can_edit: true } },
|
||||
as: :json
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "should forbid update read_only attributes - team_id" do
|
||||
patch api_v1_team_membership_url(@team, @membership),
|
||||
patch api_v1_membership_url(@membership),
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
params: { membership: { team_id: @team2.id, member_id: @user2.id } },
|
||||
as: :json
|
||||
|
|
@ -94,7 +84,7 @@ class Api::V1::MembershipsControllerTest < ActionDispatch::IntegrationTest
|
|||
# DESTROY
|
||||
test "should destroy membership" do
|
||||
assert_difference('Membership.count', -1) do
|
||||
delete api_v1_team_membership_url(@team, @membership),
|
||||
delete api_v1_membership_url(@membership),
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
as: :json
|
||||
end
|
||||
|
|
@ -103,7 +93,7 @@ class Api::V1::MembershipsControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
test "should forbid destroy membership" do
|
||||
assert_no_difference('Membership.count') do
|
||||
delete api_v1_team_membership_url(@team, @membership), as: :json
|
||||
delete api_v1_membership_url(@membership), as: :json
|
||||
end
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44,17 +44,17 @@ class Api::V1::TasksControllerTest < ActionDispatch::IntegrationTest
|
|||
test "should create task" do
|
||||
assert_difference("Task.count") do
|
||||
post api_v1_activity_tasks_url(@activity),
|
||||
params: { task: { name: @task.name, description: @task.description, owner_id: @user, start_time: DateTime.now } },
|
||||
params: { task: { name: @task.name, description: @task.description, owner_id: @user, activity_id: @activity, start_time: DateTime.now } },
|
||||
headers: { Authorization: JsonWebToken.encode(user_id: @user.id) },
|
||||
as: :json
|
||||
end
|
||||
assert_response :created
|
||||
end
|
||||
|
||||
test "should not create task - not logged in" do
|
||||
test "should not create task" do
|
||||
assert_no_difference("Task.count") do
|
||||
post api_v1_activity_tasks_url(@activity),
|
||||
params: { task: { name: @task.name, description: @task.description, owner_id: @user } },
|
||||
params: { task: { name: @task.name, description: @task.description, owner_id: @user, activity_id: @activity } },
|
||||
as: :json
|
||||
end
|
||||
assert_response :forbidden
|
||||
|
|
|
|||
5
test/fixtures/memberships.yml
vendored
5
test/fixtures/memberships.yml
vendored
|
|
@ -8,3 +8,8 @@ one:
|
|||
team: one
|
||||
member: one
|
||||
can_edit: true
|
||||
|
||||
two:
|
||||
team: one
|
||||
member: two
|
||||
can_edit: false
|
||||
|
|
|
|||
107
test/remote/NRT/Batch.pm
Normal file
107
test/remote/NRT/Batch.pm
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
use NRT::Test;
|
||||
use NRT::Helper;
|
||||
use NRT::User;
|
||||
use NRT::Activity;
|
||||
use NRT::Task;
|
||||
|
||||
package Batch;
|
||||
|
||||
sub new {
|
||||
my ($classe, %config) = @_;
|
||||
my $this = {};
|
||||
$classe = ref($classe) || $classe;
|
||||
bless ( $this, $classe );
|
||||
$this->{config} = {%config} ;
|
||||
$this->{tester} = Test->new( %config );
|
||||
$this->{users} = [];
|
||||
$this->{users_index} = 0;
|
||||
$this->{default_user_index} = "";
|
||||
return $this;
|
||||
}
|
||||
|
||||
sub test_rq_empty {
|
||||
my $this = shift;
|
||||
print "\nTesting requests\n";
|
||||
my $rq = $this->{tester}->get_code();
|
||||
return $this->{tester}->assertEqual( $rq, "404 Not Found" );
|
||||
}
|
||||
|
||||
sub test_user {
|
||||
my $this = shift;
|
||||
print "\nTesting users\n";
|
||||
$this->{tester}->test_user_authentification( $this->get_default_user );
|
||||
$this->{tester}->test_user_already_created( $this->get_default_user );
|
||||
my $user2_index = $this->add_user(
|
||||
$this->{config}{User}{Email},
|
||||
$this->{config}{User}{Username},
|
||||
$this->{config}{User}{Password} );
|
||||
$this->{tester}->test_user_not_exists(
|
||||
$this->{users}[$user2_index]);
|
||||
$this->{tester}->test_user_create(
|
||||
$this->{users}[$user2_index]);
|
||||
$this->{tester}->test_user_exists(
|
||||
$this->{users}[$user2_index]);
|
||||
$this->{tester}->test_user_remove(
|
||||
$this->{users}[$user2_index]);
|
||||
$this->{tester}->test_user_removed(
|
||||
$this->{users}[$user2_index]);
|
||||
$this->{tester}->test_user_already_removed(
|
||||
$this->{users}[$user2_index]);
|
||||
}
|
||||
|
||||
sub add_user {
|
||||
my ($this, $email, $username, $password) = @_ ;
|
||||
push(
|
||||
@{$this->{users}},
|
||||
User->new( $email, $username, $password, $this->{tester})) ;
|
||||
return $this->{users_index}++;
|
||||
}
|
||||
|
||||
sub add_default_user {
|
||||
my ($this) = @_ ;
|
||||
return $this->{default_user_index} = $this->add_user(
|
||||
$this->{config}{Authentification}{Email},
|
||||
$this->{config}{Authentification}{Username},
|
||||
$this->{config}{Authentification}{Password} )
|
||||
}
|
||||
|
||||
sub get_default_user {
|
||||
my ($this) = @_ ;
|
||||
if( $this->{default_user_index} eq "" ){
|
||||
$this->add_default_user ;
|
||||
}
|
||||
return $this->{users}[ $this->{default_user_index} ];
|
||||
}
|
||||
|
||||
sub test_activity {
|
||||
my $this = shift;
|
||||
print "\nTesting activities\n";
|
||||
my $activity = Activity->new( "test_1", $this->get_default_user );
|
||||
$this->{tester}->test_create_activity( $activity );
|
||||
$this->{tester}->test_activity_exists( $activity );
|
||||
my $task = Task->new( "test_1", $activity );
|
||||
$this->{tester}->test_task_not_exists( $task );
|
||||
$this->{tester}->test_create_task( $task );
|
||||
$this->{tester}->test_task_exists( $task );
|
||||
$this->{tester}->test_task_remove( $task );
|
||||
$this->{tester}->test_task_not_exists( $task );
|
||||
$this->{tester}->test_activity_remove( $activity );
|
||||
$this->{tester}->test_activity_not_exists( $activity );
|
||||
}
|
||||
|
||||
sub run {
|
||||
my $this = shift;
|
||||
$this->test_rq_empty();
|
||||
$this->test_user();
|
||||
$this->test_activity();
|
||||
$this->brief();
|
||||
}
|
||||
|
||||
sub brief {
|
||||
my $this = shift;;
|
||||
print "\nResults :\n";
|
||||
Helper::printColor( "bright_green", "Tests succeed : ".$this->{tester}->{countSuccess}."\n" );
|
||||
Helper::printColor( "bright_red", "Tests failed : ".$this->{tester}->{countFailure}."\n" );
|
||||
}
|
||||
|
||||
return 1;
|
||||
13
test/remote/NRT/Helper.pm
Normal file
13
test/remote/NRT/Helper.pm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use Term::ANSIColor;
|
||||
|
||||
package Helper;
|
||||
|
||||
sub printColor {
|
||||
my $color = (exists $_[0])? $_[0] : "";
|
||||
my $text = (exists $_[0])? $_[1] : "";
|
||||
print Term::ANSIColor::color( "$color" );
|
||||
print "$text";
|
||||
print Term::ANSIColor::color('reset')
|
||||
}
|
||||
|
||||
return 1;
|
||||
231
test/remote/NRT/Test.pm
Normal file
231
test/remote/NRT/Test.pm
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
use NRT::Helper;
|
||||
use LWP::UserAgent;
|
||||
|
||||
package Test;
|
||||
require Exporter;
|
||||
|
||||
sub new {
|
||||
my ($classe, %config) = @_;
|
||||
my $this = {};
|
||||
$classe = ref($classe) || $classe;
|
||||
bless ( $this, $classe );
|
||||
$this->{url} = "$config{Authentification}{Protocol}$config{Authentification}{Host}$config{Authentification}{Path}";
|
||||
$this->{ua} = LWP::UserAgent->new(timeout => 10);
|
||||
$this->{ua}->env_proxy;
|
||||
$this->{countSuccess} = 0;
|
||||
$this->{countFailure} = 0;
|
||||
return $this;
|
||||
}
|
||||
|
||||
sub rq {
|
||||
my $this = shift ;
|
||||
my $path = (exists $_[0])? $_[0] : "";
|
||||
my $method = (exists $_[1])? $_[1] : "";
|
||||
my $content = (exists $_[2])? $_[2] : "";
|
||||
my $authorization = (exists $_[3])? $_[3] : "";
|
||||
|
||||
my $req = HTTP::Request->new( $method, "$this->{url}$path" );
|
||||
$req->header( 'Content-Type' => 'application/json' );
|
||||
|
||||
if( $authorization ){
|
||||
$req->header(Authorization => $authorization);
|
||||
}
|
||||
|
||||
$req->content( $content );
|
||||
my $res = $this->{ua}->request($req) ;
|
||||
|
||||
return ( $res->is_success() && $this->is_json( $res->decoded_content ) )?
|
||||
$this->json_parse( $res->decoded_content )
|
||||
: $res->status_line();
|
||||
}
|
||||
|
||||
sub assertEqual {
|
||||
my ($this, $value1, $value2, $equal ) = @_;
|
||||
$equal //= 1;
|
||||
my $success = 0;
|
||||
|
||||
my $test = ( $value1 eq $value2 );
|
||||
$test = ( $equal )? $test : !$test;
|
||||
$assertedComparator = ($equal)? "equal" : "NOT equal" ;
|
||||
$unassertedComparator = ($equal)? "NOT equal" : "equal" ;
|
||||
|
||||
if( $test )
|
||||
{
|
||||
$this->record_result( 1 );
|
||||
print " $value1 ";
|
||||
Helper::printColor( "bright_blue", $assertedComparator);
|
||||
print " $value2\n";
|
||||
return 1;
|
||||
}else{
|
||||
$this->record_result( 0 );
|
||||
print " $value1 ";
|
||||
Helper::printColor( "bright_blue", $assertedComparator);
|
||||
print " $value2\n";
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
sub assertNotEqual {
|
||||
my $this = shift;
|
||||
return $this->assertEqual( $_[0], $_[1], 0 );
|
||||
}
|
||||
|
||||
sub get_code {
|
||||
my ($this, $path) = @_;
|
||||
if(!defined $path){
|
||||
$path = "";
|
||||
#exit 1;
|
||||
}
|
||||
my $response = $this->{ua}->get( "$this->{url}$path" );
|
||||
|
||||
if ($response->is_success) {
|
||||
return $response->decoded_content;
|
||||
}else{
|
||||
return $response->status_line;
|
||||
}
|
||||
}
|
||||
|
||||
sub record_result {
|
||||
my $this = shift ;
|
||||
my $status = (exists $_[0])? $_[0] : false;
|
||||
|
||||
if( $status ){
|
||||
Helper::printColor( "green", "Success :");
|
||||
$this->{countSuccess}++;
|
||||
}else{
|
||||
Helper::printColor( "red", "Failure :");
|
||||
$this->{countFailure}++;
|
||||
}
|
||||
}
|
||||
|
||||
sub json_parse {
|
||||
my ($this, $json_text) = @_;
|
||||
my $json = JSON->new;
|
||||
$res = eval{ $json->decode("$json_text") };
|
||||
return ($@)?
|
||||
0 :
|
||||
$res ;
|
||||
}
|
||||
|
||||
sub is_json {
|
||||
my ($this, $json_text) = @_;
|
||||
my $json = JSON->new;
|
||||
$res = eval{ $json->decode("$json_text") };
|
||||
return ($@)? 0 : 1 ;
|
||||
}
|
||||
|
||||
sub get_countSuccess {
|
||||
my $this = shift;
|
||||
return $this->{countSuccess} ;
|
||||
}
|
||||
|
||||
sub get_countFailure{
|
||||
return $countFailure ;
|
||||
}
|
||||
|
||||
sub get_url{
|
||||
my $this = shift;
|
||||
return $this->{url} ;
|
||||
}
|
||||
|
||||
sub test_rq_empty {
|
||||
my $this = shift;
|
||||
my $rq = $this->get_code();
|
||||
return $this->assertEqual( $rq, "404 Not Found" );
|
||||
}
|
||||
|
||||
sub test_user_authentification {
|
||||
my ($this, $user) = @_;
|
||||
my $auth = $user->authentification;
|
||||
return $this->assertEqual( $auth->{email}, $user->{email} );
|
||||
}
|
||||
|
||||
sub test_user_exists {
|
||||
my ($this, $user) = @_;
|
||||
my $ruser = $user->fetch;
|
||||
return $this->assertEqual( $ruser->{data}{attributes}{email}, $user->{email} );
|
||||
}
|
||||
|
||||
sub test_user_not_exists {
|
||||
my ($this, $user) = @_;
|
||||
return $this->assertNotEqual( $ruser->{data}{attributes}{email}, $user->{email} );
|
||||
}
|
||||
|
||||
sub test_user_create {
|
||||
my ($this, $user) = @_;
|
||||
my $creation = $user->create();
|
||||
return $this->assertEqual( $creation->{data}{attributes}{email}, $user->{email} );
|
||||
}
|
||||
|
||||
sub test_user_already_removed {
|
||||
my ($this, $user) = @_;
|
||||
return $this->assertEqual($user->remove, '404 Not Found');
|
||||
}
|
||||
|
||||
sub test_user_removed {
|
||||
my ($this, $user) = @_;
|
||||
my $user = $user->fetch();
|
||||
return $this->assertEqual( $user, '404 Not Found' );
|
||||
}
|
||||
|
||||
sub test_user_remove {
|
||||
my ($this, $user) = @_;
|
||||
return $this->assertEqual( $user->remove, '204 No Content');
|
||||
}
|
||||
|
||||
sub test_user_already_created {
|
||||
my ($this, $user) = @_;
|
||||
my $creation = $user->fetch;
|
||||
return $this->assertEqual( $creation->{data}{id}, $user->get_id);
|
||||
}
|
||||
|
||||
sub test_create_activity {
|
||||
my ($this, $activity) = @_;
|
||||
my $res = $activity->create;
|
||||
return $this->assertEqual( $res->{data}{attributes}{name}, $activity->{name} );
|
||||
}
|
||||
|
||||
sub test_activity_remove {
|
||||
my ($this, $activity) = @_;
|
||||
$activity->remove;
|
||||
return $this->assertNotEqual( $ractivity->{data}{id}, $activity->{id} );
|
||||
}
|
||||
|
||||
sub test_activity_exists {
|
||||
my ($this, $activity) = @_;
|
||||
my $ractivity = $activity->fetch;
|
||||
return $this->assertEqual( $ractivity->{data}{id}, $activity->{id} );
|
||||
}
|
||||
|
||||
sub test_activity_not_exists {
|
||||
my ($this, $activity) = @_;
|
||||
my $ractivity = $activity->fetch;
|
||||
return $this->assertNotEqual( $ractivity->{data}{id}, $activity->{id} );
|
||||
}
|
||||
|
||||
sub test_create_task {
|
||||
my ($this, $task) = @_;
|
||||
my $res = $task->create;
|
||||
return $this->assertEqual( $res->{data}{attributes}{name}, $task->{name} );
|
||||
}
|
||||
|
||||
sub test_task_exists {
|
||||
my ($this, $task) = @_;
|
||||
my $rtask = $task->fetch;
|
||||
return $this->assertEqual( $rtask->{data}{id}, $task->{id} );
|
||||
}
|
||||
|
||||
sub test_task_not_exists {
|
||||
my ($this, $task) = @_;
|
||||
my $rtask = $task->fetch;
|
||||
eval {exists $rtask->{data}{id}};
|
||||
return $this->assertNotEqual( $@, 0 );
|
||||
}
|
||||
|
||||
sub test_task_remove {
|
||||
my ($this, $task) = @_;
|
||||
my $rtask = $task->remove;
|
||||
return $this->assertNotEqual( $rtask->{data}{id}, $task->{id} );
|
||||
}
|
||||
|
||||
return 1;
|
||||
85
test/remote/NRT/User.pm
Normal file
85
test/remote/NRT/User.pm
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
use LWP::Simple;
|
||||
use NRT::Test;
|
||||
use NRT::Activity;
|
||||
use Crypt::JWT(decode_jwt);
|
||||
|
||||
package User;
|
||||
|
||||
sub new {
|
||||
my ($classe, $email, $username, $password, $manager) = @_;
|
||||
my $this = {};
|
||||
$classe = ref($classe) || $classe;
|
||||
bless ( $this, $classe );
|
||||
$this->{email} = $email;
|
||||
$this->{username} = $username;
|
||||
$this->{password} = $password;
|
||||
$this->{manager} = $manager;
|
||||
$this->{token} = "";
|
||||
$this->{id} = "";
|
||||
$this->{activities} = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
sub authentification {
|
||||
my $this = shift ;
|
||||
my $data = "{\"user\" : {\"email\" : \"".$this->{email}."\", \"password\" : \"".$this->{password}."\"}}";
|
||||
$rq = $this->{manager}->rq( "tokens", "POST", $data ); ;
|
||||
$this->{token} = $rq->{token} ;
|
||||
return $rq;
|
||||
}
|
||||
|
||||
sub create {
|
||||
my ($this) = shift ;
|
||||
my $data = "{\"user\" : {\"username\" : \"". $this->{username} ."\", \"email\" : \"".$this->{email}."\", \"password\" : \"".$this->{password}."\"}}";
|
||||
$rq = $this->{manager}->rq( "users", "POST", "$data" );
|
||||
$this->{id} = $rq->{data}{id};
|
||||
return $rq;
|
||||
}
|
||||
|
||||
sub remove {
|
||||
my ($this) = @_ ;
|
||||
my $data = "{\"user\" : {\"username\" : \"". $this->{username} ."\", \"email\" : \"".$this->{email}."\", \"password\" : \"".$this->{password}."\"}}";
|
||||
my $user_id = Crypt::JWT::decode_jwt(token => $this->get_token, ignore_signature => 1)->{user_id};
|
||||
return $this->{manager}->rq( "users/".$user_id, "DELETE", $data, $this->get_token );
|
||||
}
|
||||
|
||||
sub fetch {
|
||||
my ($this) = @_ ;
|
||||
return $this->{manager}->rq(
|
||||
"users/".$this->get_id,
|
||||
"GET",
|
||||
"",
|
||||
$this->get_token );
|
||||
}
|
||||
|
||||
sub get_token {
|
||||
my $this = shift;
|
||||
if ($this->{token} eq ""){
|
||||
$this->authentification;
|
||||
}
|
||||
return (exists $this->{token})?
|
||||
$this->{token} :
|
||||
0 ;
|
||||
}
|
||||
|
||||
sub get_id {
|
||||
my $this = shift;
|
||||
if( !($this->{id} eq "") ){
|
||||
return $this->{id};
|
||||
}
|
||||
$token = $this->get_token;
|
||||
if( !$token ){
|
||||
return 0;
|
||||
}
|
||||
return Crypt::JWT::decode_jwt(token => $token, ignore_signature => 1)->{user_id};
|
||||
}
|
||||
|
||||
sub create_activity {
|
||||
my ($this, $name) = @_;
|
||||
my $activity = Activity->new(
|
||||
$name,
|
||||
$this);;
|
||||
return $activity;
|
||||
}
|
||||
|
||||
return 1;
|
||||
6
test/remote/install.sh
Normal file
6
test/remote/install.sh
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
echo "\nInstalling PERL dependancies\n"
|
||||
echo "Will use cpan. If you would not install cpan, you may need to manually download and install these.\n"
|
||||
cpan install LWP::UserAgent
|
||||
cpan install HTTP::Request
|
||||
cpan install JSON::WebToken
|
||||
cpan install Crypt::JWT
|
||||
12
test/remote/test.cfg.sample
Normal file
12
test/remote/test.cfg.sample
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[Authentification]
|
||||
Protocol : https://
|
||||
Host : localhost/
|
||||
Path : api/v1/
|
||||
Email : test@cli.su
|
||||
Username : test_remote
|
||||
Password : NJfccjabWSXqmpTRhfXRs6Re2CAIsJyhz3TAo4rpWz2nlMgWqTScmbsXoIlwdHB1
|
||||
|
||||
[Users]
|
||||
Userame : perl_test
|
||||
Password : letestdesesgrandsmorts
|
||||
Email : test@perl.su
|
||||
20
test/remote/test.pl
Normal file
20
test/remote/test.pl
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/perl
|
||||
# @file journal.pl
|
||||
# @author nas
|
||||
# @date 31/01/2022
|
||||
# @brief Remote call to the API in order to test
|
||||
BEGIN { push @INC,'.'; };
|
||||
use Config::Std;
|
||||
use LWP::UserAgent;
|
||||
use lib qw(..);
|
||||
use JSON qw( );
|
||||
use Data::Dumper;
|
||||
|
||||
use NRT::Batch;
|
||||
|
||||
print User::v ;
|
||||
read_config 'test.cfg' => our %config;
|
||||
our $batch = Batch->new( %config );
|
||||
print "\nMaking all tests\n";
|
||||
|
||||
print Dumper $batch->run();
|
||||
Loading…
Add table
Add a link
Reference in a new issue