Skip to content
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

Extended courses resource. #12

Open
wants to merge 4 commits into
base: master
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
1 change: 1 addition & 0 deletions lib/kosapi_client/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'kosapi_client/entity/data_mappings'
require 'kosapi_client/entity/base_entity'
require 'kosapi_client/entity/result_page'
require 'kosapi_client/entity/coursin'
require 'kosapi_client/entity/course_event'
require 'kosapi_client/entity/course'
require 'kosapi_client/entity/timetable_slot'
Expand Down
17 changes: 17 additions & 0 deletions lib/kosapi_client/entity/coursin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module KOSapiClient
module Entity
class Coursin < BaseEntity

map_data :capacity
map_data :capacity_overfill, Integer
map_data :course # TODO: fix circular reference. map_data :course, Course
map_data :occupied, Integer
map_data :semester
map_data :tutorial_capacity, Integer
map_data :examiners, [Link], array_wrapper_element: :teacher
map_data :guarantors, [Link], array_wrapper_element: :teacher
map_data :instructors, [Link], array_wrapper_element: :teacher
map_data :lecturers, [Link], array_wrapper_element: :teacher
end
end
end
5 changes: 5 additions & 0 deletions lib/kosapi_client/entity/data_mappings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,17 @@ def set_mapped_attributes(instance, source_hash)
def set_mapped_attribute(instance, name, source_hash, mapping_options)
namespace = mapping_options[:namespace]
src_element = mapping_options[:element] || name

if namespace
key = "#{namespace}_#{src_element}".to_sym
else
key = src_element
end

value = source_hash[key]

value = value[mapping_options[:array_wrapper_element]] if mapping_options.key? :array_wrapper_element

if value.nil?
raise "Missing value for attribute #{name}" if mapping_options[:required]
if mapping_options[:type].is_a?(Array)
Expand Down
5 changes: 5 additions & 0 deletions lib/kosapi_client/request_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ def limit(num)
self
end

def sem(code)
@url_builder.set_query_param(:sem, code)
self
end

def query(params = {})
raise 'Empty parameters to query are not allowed' if params.empty?
if params.instance_of?(String)
Expand Down
55 changes: 55 additions & 0 deletions lib/kosapi_client/resource/courses_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,61 @@ def detail(level = 1)
self
end

###
# GET /courses/{code}/parallels
#
# URI: https://kosapi.fit.cvut.cz/api/3/courses/{code}/parallels/
# @link: https://kosapi.fit.cvut.cz/projects/kosapi/wiki/Courses#GET-coursescodeparallels
##
# Example:
# client.courses.find({course_code}).parallels
# client.courses.find({course_code}).sem({semester_code}).parallels
###
def parallels
raise 'Call #find before asking for parallels' unless id_set?
url_builder.set_path(id, 'parallels')
self
end

###
# GET /courses/{code}/students
#
# URI: https://kosapi.fit.cvut.cz/api/3/courses/{code}/students/
# @link: https://kosapi.fit.cvut.cz/projects/kosapi/wiki/Courses#GET-coursescodestudents
##
# Example:
# client.courses.find({course_code}).students
# client.courses.find({course_code}).sem({semester_code}).students
###
def students
raise 'Call #find before asking for students' unless id_set?
url_builder.set_path(id, 'students')
self
end

###
# GET /courses/{code}/instances
#
# URI: https://kosapi.fit.cvut.cz/api/3/courses/{code}/instances/
# @link: https://kosapi.fit.cvut.cz/projects/kosapi/wiki/Courses#GET-coursescodeinstances
##
# Example:
# client.courses.find({course_code}).instances
###
def instances
raise 'Call #find before asking for course instances' unless id_set?
url_builder.set_path(id, 'instances')
self
end

###
# GET /courses/{code}/instances/{semester}
###
def instance(semester)
raise 'Call #find before asking for course instance' unless id_set?
url_builder.set_path(id, 'instances', semester)
finalize
end
end
end
end
20 changes: 20 additions & 0 deletions spec/integration/courses_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,24 @@
expect(page.items).to eq []
end

describe "#parallels" do
it 'returns parallels for course in specified semester' do
parallels = client.courses.find('MI-PAA').sem('B141').parallels.limit(20)
expect(parallels.count).to eq 9
end
end

describe "#students" do
it 'returns students of course in specified semester' do
students = client.courses.find('MI-PAA').sem('B141').students.limit(200)
expect(students.count).to eq 188
end
end

describe "#instance" do
it 'returns instance for course in specified semester' do
instance = client.courses.find('MI-PAA').instance('B141')
expect(instance).to be_a KOSapiClient::Entity::Coursin
end
end
end
2 changes: 1 addition & 1 deletion spec/integration/parallels_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
end

it 'parses timetable slot ID' do
page = client.parallels
page = client.parallels.query('course.code' => 'MI-PAA')
slot = page.items.first.timetable_slots.first
expect(slot.id).not_to be_nil
end
Expand Down
8 changes: 8 additions & 0 deletions spec/kosapi_client/entity/data_mappings_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@
expect(instance.foo).to eq '123'
end

it 'supports array wrapping element name configuration' do
dummy_class.map_data :foo, String, array_wrapper_element: :bar
instance = dummy_class.parse(foo: {bar: ['123','456']})
expect(instance.foo).to be_a Array
expect(instance.foo.count).to eq 2
expect(instance.foo.first).to eq '123'
end

end

describe '#to_hash' do
Expand Down
73 changes: 73 additions & 0 deletions spec/kosapi_client/resource/courses_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,77 @@
end

end

describe '#students' do

before { allow(url_builder).to receive(:set_path) }

it 'throws error when course id not set' do
expect { builder.students }.to raise_error(RuntimeError)
end

it 'returns self' do
builder.find(42)
expect(builder.students).to eq builder
end

it 'adds students to URL' do
expect(url_builder).to receive(:set_path).with(42, 'students')
builder.find(42).students
end
end

describe '#parallels' do

before { allow(url_builder).to receive(:set_path) }

it 'throws error when course id not set' do
expect { builder.parallels }.to raise_error(RuntimeError)
end

it 'returns self' do
builder.find(42)
expect(builder.parallels).to eq builder
end

it 'adds students to URL' do
expect(url_builder).to receive(:set_path).with(42, 'parallels')
builder.find(42).parallels
end
end

describe '#instances' do

before { allow(url_builder).to receive(:set_path) }

it 'throws error when course id not set' do
expect { builder.instances }.to raise_error(RuntimeError)
end

it 'returns self' do
builder.find(42)
expect(builder.instances).to eq builder
end

it 'adds instances to URL' do
expect(url_builder).to receive(:set_path).with(42, 'instances')
builder.find(42).instances
end
end

describe '#instance' do

before { allow(url_builder).to receive(:set_path) }

it 'throws error when course id not set' do
expect { builder.instance('foo') }.to raise_error(RuntimeError)
end

it 'adds instance to URL' do
expect(url_builder).to receive(:set_path).with(42)
expect(url_builder).to receive(:set_path).with(42, 'instances', 'foo')
builder.find(42).instance('foo')
end
end

end