-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add CreateMovies migration * feat: implement MoviesRepository and UCs * test: write MoviesRepository spec * test: write Movie model spec * test: write Movies:Create spec * test: write Movies:Find spec * feat: implement index and create endpoints + tests * chore: update movie create use case * feat: delete movie use case * feat: find by id movie use case * chore: update movie find use case * feat: implement update movie use case * feat: implement show, update and delete endpoints * test: write tests * chore: code review I
- Loading branch information
1 parent
d24c79d
commit 292a302
Showing
23 changed files
with
630 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
class MoviesController < ApplicationController | ||
rescue_from ActiveRecord::RecordNotFound, with: :movie_not_found | ||
|
||
def index | ||
render json: Movies::Find.new.call | ||
end | ||
|
||
def create | ||
movie = Movies::Create.new(params: movie_params).call! | ||
|
||
render json: movie, status: :created | ||
rescue ActiveRecord::RecordInvalid | ||
render json: { error: "Could not create a movie" }, status: :unprocessable_entity | ||
end | ||
|
||
def update | ||
Movies::Update.new(params: movie_params.merge(id: params[:id]), movie: Movie).call! | ||
|
||
render status: :no_content | ||
rescue ActiveRecord::RecordInvalid | ||
render json: { error: "Could not update a movie" }, status: :unprocessable_entity | ||
end | ||
|
||
def show | ||
movie = Movies::FindById.new(id: params[:id]).call | ||
|
||
render json: movie | ||
end | ||
|
||
def destroy | ||
Movies::Delete.new(id: params[:id]).call | ||
|
||
render status: :no_content | ||
end | ||
|
||
private | ||
|
||
def movie_params | ||
params | ||
.require(:movie) | ||
.permit(:director, :writer, :title, :producer, :production_company, :year, cast: []) | ||
end | ||
|
||
def movie_not_found | ||
render json: { error: "Movie not found" }, status: :not_found | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
class Movie | ||
attr_accessor :id, :director, :writer, :title, :producer, :production_company, :cast, :year, :created_at, :updated_at | ||
|
||
def initialize(id: nil, director:, writer:, title:, producer:, production_company:, cast:, year:, created_at: nil, updated_at: nil) | ||
@id = id | ||
@director = director | ||
@writer = writer | ||
@title = title | ||
@producer = producer | ||
@production_company = production_company | ||
@cast = cast | ||
@year = year | ||
@created_at = created_at | ||
@updated_at = updated_at | ||
end | ||
|
||
def to_hash | ||
{ | ||
id: @id, | ||
director: @director, | ||
writer: @writer, | ||
title: @title, | ||
producer: @producer, | ||
production_company: @production_company, | ||
cast: @cast, | ||
year: @year, | ||
created_at: @created_at, | ||
updated_at: @updated_at | ||
}.compact | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
class MoviesRepository < ActiveRecord::Base | ||
self.table_name = 'movies' | ||
|
||
validates_presence_of :director, :writer, :title, :producer, :cast, :year | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
class Movies::Create | ||
def initialize(params:, movie: Movie, repository: MoviesRepository) | ||
@params = params | ||
@movie = movie | ||
@repository = repository | ||
end | ||
|
||
def call! | ||
movie = @movie.new( | ||
director: @params[:director], | ||
writer: @params[:writer], | ||
title: @params[:title], | ||
producer: @params[:producer], | ||
production_company: @params[:production_company], | ||
cast: @params[:cast], | ||
year: @params[:year] | ||
) | ||
|
||
result = @repository.create!(movie.to_hash) | ||
movie.id = result.id | ||
movie.created_at = result.created_at | ||
movie.updated_at = result.updated_at | ||
|
||
movie | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class Movies::Delete | ||
def initialize(id:, repository: MoviesRepository) | ||
@id = id | ||
@repository = repository | ||
end | ||
|
||
def call | ||
@repository.delete(@id) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
class Movies::Find | ||
def initialize(repository: MoviesRepository) | ||
@repository = repository | ||
end | ||
|
||
def call | ||
@repository.all.map do |movie| | ||
Movie.new( | ||
id: movie.id, | ||
director: movie.director, | ||
writer: movie.writer, | ||
title: movie.title, | ||
producer: movie.producer, | ||
production_company: movie.production_company, | ||
cast: JSON.parse(movie.cast), | ||
year: movie.year, | ||
created_at: movie.created_at, | ||
updated_at: movie.updated_at | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
class Movies::FindById | ||
def initialize(id:, repository: MoviesRepository) | ||
@id = id | ||
@repository = repository | ||
end | ||
|
||
def call | ||
movie = @repository.find(@id) | ||
|
||
Movie.new( | ||
id: movie.id, | ||
director: movie.director, | ||
writer: movie.writer, | ||
title: movie.title, | ||
producer: movie.producer, | ||
production_company: movie.production_company, | ||
cast: JSON.parse(movie.cast), | ||
year: movie.year, | ||
created_at: movie.created_at, | ||
updated_at: movie.updated_at | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
class Movies::Update | ||
def initialize(params:, movie: Movie, repository: MoviesRepository) | ||
@params = params | ||
@movie = movie | ||
@repository = repository | ||
end | ||
|
||
def call! | ||
movie = @movie.new( | ||
id: @params[:id], | ||
director: @params[:director], | ||
writer: @params[:writer], | ||
title: @params[:title], | ||
producer: @params[:producer], | ||
production_company: @params[:production_company], | ||
cast: @params[:cast], | ||
year: @params[:year] | ||
) | ||
|
||
current_movie = @repository.find(movie.id) | ||
current_movie.update!(movie.to_hash) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
class CreateMovies < ActiveRecord::Migration[7.0] | ||
def change | ||
create_table :movies do |t| | ||
t.string :director | ||
t.string :writer | ||
t.string :title | ||
t.string :producer | ||
t.string :production_company | ||
t.string :cast, array: true | ||
t.integer :year | ||
|
||
t.timestamps | ||
end | ||
end | ||
end |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe Movie do | ||
describe '.to_hash' do | ||
let(:movie_id) { 1 } | ||
let(:movie) { | ||
described_class.new( | ||
id: movie_id, | ||
director: "George Lucas", | ||
writer: "George Lucas", | ||
title: "Star Wars", | ||
producer: "George Lucas", | ||
production_company: "Lucasfilm", | ||
cast: ["Han Solo", "Princess Leia"], | ||
year: 1977 | ||
) | ||
} | ||
|
||
context 'when movie id is present' do | ||
it 'returns movie hash' do | ||
expect(movie.to_hash).to eq({ | ||
id: movie_id, | ||
director: "George Lucas", | ||
writer: "George Lucas", | ||
title: "Star Wars", | ||
producer: "George Lucas", | ||
production_company: "Lucasfilm", | ||
cast: ["Han Solo", "Princess Leia"], | ||
year: 1977 | ||
}) | ||
end | ||
end | ||
|
||
context 'when movie id is not present' do | ||
let(:movie_id) { nil } | ||
|
||
it 'returns movie hash without id' do | ||
expect(movie.to_hash).to eq({ | ||
director: "George Lucas", | ||
writer: "George Lucas", | ||
title: "Star Wars", | ||
producer: "George Lucas", | ||
production_company: "Lucasfilm", | ||
cast: ["Han Solo", "Princess Leia"], | ||
year: 1977 | ||
}) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe MoviesRepository, type: :model do | ||
it { is_expected.to validate_presence_of(:title) } | ||
it { is_expected.to validate_presence_of(:year) } | ||
it { is_expected.to validate_presence_of(:director) } | ||
it { is_expected.to validate_presence_of(:writer) } | ||
it { is_expected.to validate_presence_of(:producer) } | ||
it { is_expected.to validate_presence_of(:cast) } | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe "Movies", type: :request do | ||
let(:response_json) { JSON.parse(response.body) } | ||
|
||
let(:params) do | ||
{ | ||
"movie" => { | ||
"director" => "George Lucas", | ||
"writer" => "George Lucas", | ||
"title" => "Star Wars", | ||
"producer" => "George Lucas", | ||
"production_company" => "Lucasfilm", | ||
"cast" => ["Han Solo", "Princess Leia"], | ||
"year" => 1977 | ||
} | ||
} | ||
end | ||
|
||
describe "POST /api/movies" do | ||
context "when create params are valid" do | ||
it "responds with 201" do | ||
expect { post "/api/movies", params: params } | ||
.to change { MoviesRepository.count }.by(1) | ||
|
||
expect(response).to have_http_status(:created) | ||
end | ||
end | ||
|
||
context "when create params are invalid" do | ||
it "responds with 422" do | ||
post "/api/movies", params: { "movie" => { "title" => "", "year" => "" } } | ||
|
||
expect(response_json).to eq({ "error" => "Could not create a movie" }) | ||
expect(response).to have_http_status(:unprocessable_entity) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe "Movies", type: :request do | ||
describe "DELETE /api/movies/:id" do | ||
context "when movie exists" do | ||
let!(:movie) { | ||
Movies::Create.new( | ||
params: { | ||
director: "George Lucas", | ||
writer: "George Lucas", | ||
title: "Star Wars", | ||
producer: "George Lucas", | ||
production_company: "Lucasfilm", | ||
cast: ["Han Solo", "Princess Leia"], | ||
year: 1977 | ||
} | ||
).call! | ||
} | ||
|
||
it "responds with 204" do | ||
expect { delete "/api/movies/#{movie.id}" } | ||
.to change { MoviesRepository.count }.by(-1) | ||
|
||
expect(response).to have_http_status(:no_content) | ||
end | ||
end | ||
|
||
context "when movie does not exist" do | ||
it "responds with 204" do | ||
delete "/api/movies/123" | ||
|
||
expect(response).to have_http_status(:no_content) | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.