Skip to content

Axel's task #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@

# Ignore master key for decrypting credentials and more.
/config/master.key

# IDE settings
.idea
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby 2.7.7
27 changes: 26 additions & 1 deletion app/controllers/courses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ class CoursesController < ApplicationController

# GET /courses
def index
@courses = Course.all
@courses = filter_courses(Course.all)

render json: @courses
end

# GET /courses/1
Expand Down Expand Up @@ -45,6 +47,21 @@ def destroy
redirect_to courses_url, notice: 'Course was successfully destroyed.'
end

def check_membership
begin
collection = Collection.find(params[:collection_id])
course = Course.find(params[:course_id])

belongs_to_collection = collection.courses.exists?(course.id)

render json: { belongs_to_collection: belongs_to_collection }
rescue ActiveRecord::RecordNotFound => e
render json: { error: 'Collection or course not found' }, status: :not_found
rescue => e
render json: { error: 'Unexpected error ' }, status: :internal_server_error
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_course
Expand All @@ -55,4 +72,12 @@ def set_course
def course_params
params.require(:course).permit(:title, :description, :published)
end

def filter_courses(courses)
if params[:published].present?
courses.where(published: params[:published])
else
courses
end
end
end
12 changes: 12 additions & 0 deletions app/graphql/mutations/publish_course_mutation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Mutations
class PublishCourseMutation < BaseMutation
argument :course_id, ID, required: true
type Types::CourseType

def resolve(course_id:)
course = Course.find(course_id)
course.update(published: true)
course
end
end
end
21 changes: 21 additions & 0 deletions app/graphql/types/collection_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Types
class CollectionType < Types::BaseObject
field :id, ID, null: false
field :title, String, null: false
field :description, String, null: true
field :image_path, String, null: true
field :published, Boolean, null: false
field :courses, [CourseType], null: true
field :largest_discount_percentage, Integer, null: true
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end

def courses
object.courses
end

def largest_discount_percentage
object.largest_discount_percentage
end
end
7 changes: 1 addition & 6 deletions app/graphql/types/mutation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@

module Types
class MutationType < Types::BaseObject
# TODO: remove me
field :test_field, String, null: false,
description: "An example field added by the generator"
def test_field
"Hello World"
end
field :publishCourse, mutation: Mutations::PublishCourseMutation
end
end
6 changes: 6 additions & 0 deletions app/graphql/types/query_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@ def nodes(ids:)
def courses
Course.all
end

field :collections, [CollectionType], null: false, description: "Returns a list of collections"

def collections
Collection.includes(:courses).all
end
end
end
6 changes: 6 additions & 0 deletions app/models/collection.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
class Collection < ApplicationRecord
has_and_belongs_to_many :courses, join_table: :collection_memberships
has_one :discount

def largest_discount_percentage
return 0 unless discount

discount.amount
end
end
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
root 'courses#index'

resources :courses
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get '/collections/:collection_id/courses/:course_id/belongs_to', to: 'courses#check_membership', as: :check_membership
end
46 changes: 45 additions & 1 deletion test/controllers/courses_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,32 @@ class CoursesControllerTest < ActionDispatch::IntegrationTest
@course = courses(:one)
end

test "should get index" do
test "should get index with all courses" do
get courses_url
assert_response :success
assert_equal Course.count, JSON.parse(response.body).size
end

test "should get index with published param as true" do
post courses_url, params: { course: { description: @course.description, title: @course.title, published: true } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: true } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: true } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: false } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: false } }
get courses_url, params: { published: true }
assert_response :success
assert_equal Course.where(published: true).count, JSON.parse(response.body).size
end

test "should get index with published param as false" do
post courses_url, params: { course: { description: @course.description, title: @course.title, published: true } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: true } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: true } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: false } }
post courses_url, params: { course: { description: @course.description, title: @course.title, published: false } }
get courses_url, params: { published: false }
assert_response :success
assert_equal Course.where(published: false).count, JSON.parse(response.body).size
end

test "should get new" do
Expand Down Expand Up @@ -45,4 +68,25 @@ class CoursesControllerTest < ActionDispatch::IntegrationTest

assert_redirected_to courses_url
end

test "should check if course belongs to a collection" do
collection = collections(:one)
course = courses(:one)
collection.courses << course

get check_membership_path(collection, course), as: :json
assert_response :success

assert_equal({ "belongs_to_collection" => true }, JSON.parse(response.body))
end

test "should check if course belongs to a collection and return false" do
collection = collections(:one)
course = courses(:one)

get check_membership_path(collection, course), as: :json
assert_response :success

assert_equal({ "belongs_to_collection" => false }, JSON.parse(response.body))
end
end
10 changes: 10 additions & 0 deletions test/fixtures/courses.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ two:
title: MyString
description: MyText
published: false

unpublished_course:
title: MyString
description: MyText
published: false

published_course:
title: MyString
description: MyText
published: true
4 changes: 2 additions & 2 deletions test/fixtures/discounts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

one:
amount: 1
references:
collection:

two:
amount: 1
references:
collection:
25 changes: 25 additions & 0 deletions test/graphql/mutations/publish_course_mutation_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'test_helper'

class PublishCourseMutationTest < ActiveSupport::TestCase
include ActionDispatch::IntegrationTest::Behavior

test 'publishes a course' do
course = courses(:unpublished_course)
assert_not course.published

query = <<~GQL
mutation {
publishCourse(input: { courseId: "#{course.id}" }) {
id
published
}
}
GQL

post '/graphql', params: { query: query }, as: :json
assert_response :success

course.reload
assert course.published
end
end