Commit 7fc6add5 authored by Zac Wood's avatar Zac Wood
Browse files

Added API documentation for Courses and Course Sections. The root URL

now redirects to the API documentation.
parent 10235c8d
Pipeline #2827 failed with stage
in 2 minutes and 19 seconds
--require spec_helper
......@@ -12,7 +12,7 @@ gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.7'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
......@@ -47,10 +47,29 @@ end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# HTTP requests
gem 'httparty'
# Working with iCalendar
gem 'icalendar'
# Parsing HTML
gem 'nokogiri'
# Easily deal with CORS
gem 'rack-cors', require: 'rack/cors'
# Parsing Excel files
gem 'rubyXL'
# Linting
gem "rubocop", "~> 0.58.2"
# RSpec
gem 'rspec-rails'
# Generate API documentation
gem 'rspec_api_documentation'
# Pretty API docs
gem "apitome"
......@@ -40,6 +40,9 @@ GEM
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
apitome (0.2.0)
kramdown
railties
arel (8.0.0)
ast (2.4.0)
bindex (0.5.0)
......@@ -57,6 +60,7 @@ GEM
coderay (1.1.2)
concurrent-ruby (1.0.5)
crass (1.0.4)
diff-lcs (1.3)
erubi (1.7.1)
ffi (1.9.25)
globalid (0.4.1)
......@@ -70,6 +74,7 @@ GEM
jbuilder (2.7.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
kramdown (1.17.0)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
......@@ -85,6 +90,7 @@ GEM
minitest (5.11.3)
multi_json (1.13.1)
multi_xml (0.6.0)
mustache (1.0.5)
nio4r (2.3.1)
nokogiri (1.8.3)
mini_portile2 (~> 2.3.0)
......@@ -132,6 +138,31 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-rails (3.8.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
rspec_api_documentation (6.0.0)
activesupport (>= 3.0.0)
mustache (~> 1.0, >= 0.99.4)
rspec (~> 3.0)
rubocop (0.58.2)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
......@@ -146,6 +177,17 @@ GEM
rubyzip (>= 1.1.6)
ruby_dep (1.5.0)
rubyzip (1.2.1)
sass (3.5.7)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (3.13.0)
childprocess (~> 0.5)
rubyzip (~> 1.2)
......@@ -164,6 +206,7 @@ GEM
sqlite3 (1.3.13)
thor (0.20.0)
thread_safe (0.3.6)
tilt (2.0.8)
turbolinks (5.1.1)
turbolinks-source (~> 5.1)
turbolinks-source (5.1.0)
......@@ -186,6 +229,7 @@ PLATFORMS
ruby
DEPENDENCIES
apitome
byebug
capybara (~> 2.13)
httparty
......@@ -198,8 +242,11 @@ DEPENDENCIES
puma (~> 3.7)
rack-cors
rails (~> 5.1.6)
rspec-rails
rspec_api_documentation
rubocop (~> 0.58.2)
rubyXL
sass-rails (~> 5.0)
selenium-webdriver
spring
spring-watcher-listen (~> 2.0.0)
......
Apitome.setup do |config|
# This determines where the Apitome routes will be mounted. Changing this to '/api/documentation' for instance would
# allow you to browse to http://localhost:3000/api/documentation to see your api documentation. Set to nil and mount
# it yourself if you need to.
config.mount_at = "/api"
# This defaults to Rails.root if left nil. If you're providing documentation for an engine using a dummy application
# it can be useful to set this to your engines root.. E.g. Application::Engine.root
config.root = nil
# This is where rspec_api_documentation outputs the JSON files. This is configurable within RAD, and so is
# configurable here.
config.doc_path = "doc/api"
# Set a parent controller that Apitome::DocsController inherits from. Useful if you want to use a custom
# `before_action`.
config.parent_controller = "ActionController::Base"
# The title of the documentation -- If your project has a name, you'll want to put it here.
config.title = "SRCT Schedules API"
# The main layout view for all documentation pages. By default this is pretty basic, but you may want to use your own
# application layout.
config.layout = "apitome/application"
# We're using highlight.js (https://github.com/isagalaev/highlight.js) for code highlighting, and it comes with some
# great themes. You can check http://softwaremaniacs.org/media/soft/highlight/test.html for themes, and enter the
# theme as lowercase/underscore.
config.code_theme = "default"
# This allows you to override the css manually. You typically want to require `apitome/application` within the
# override, but if you want to override it entirely you can do so.
config.css_override = nil
# This allows you to override the javascript manually. You typically want to require `apitome/application` within the
# override, but if you want to override it entirely you can do so.
config.js_override = nil
# You can provide a 'README' style markdown file for the documentation, which is a useful place to include general
# information. This path is relative to your doc_path configuration.
config.readme = "../api.md"
# Apitome can render the documentation into a single page that uses scrollspy, or it can render the documentation on
# individual pages on demand. This allows you to specify which one you want, as a single page may impact performance.
config.single_page = true
# You can specify how urls are formatted using a Proc or other callable object.
# Your proc will be called with a resource name or link, giving you the opportunity to modify it as necessary for in the documentation url.
config.url_formatter = -> (str) { str.gsub(/\.json$/, '').underscore.gsub(/[^0-9a-z\:]+/i, '-') }
# You can setup the docs to be loaded from a remote URL if they are
# not available in the application environment. This defaults to
# false.
config.remote_docs = false
# If the remote_docs is set to true, this URL is used as the base for
# the doc location. This should be the root of the doc location, where
# the readme is located. It uses the doc_path setting to build the
# URLs for the API documentation. This defaults to nil.
config.remote_url = nil
# If you would like to precompile your own assets, you can disable auto-compilation.
# This defaults to true
config.precompile_assets = true
end
RspecApiDocumentation.configure do |config|
# Output folder
config.docs_dir = Rails.root.join("doc", "api")
# An array of output format(s).
# Possible values are :json, :html, :combined_text, :combined_json,
# :json_iodocs, :textile, :markdown, :append_json
config.format = :JSON
config.request_headers_to_include = []
config.response_headers_to_include = []
end
......@@ -6,5 +6,5 @@ Rails.application.routes.draw do
resources :schedules, only: [:index]
end
root 'courses#index' # Set the root to be the courses API endpoint
get '/', to: redirect('/api')
end
Schedules API
=====================
Welcome to the SRCT Schedules API documentation. Here you can find descriptions and examples of all of the endpoints served.
{
"resource": "Course Sections",
"resource_explanation": "A way to search across the different course sections (i.e. CS 112 001, ECON 103 104) for each course",
"http_method": "GET",
"route": "/api/course_sections",
"description": "Search by course",
"explanation": null,
"parameters": [
{
"type": "number",
"name": "course_id",
"description": " course"
},
{
"type": "string",
"name": "crn",
"description": " crn"
}
],
"response_fields": [
],
"requests": [
{
"request_method": "GET",
"request_path": "/api/course_sections?course_id=169421928",
"request_body": null,
"request_headers": {
},
"request_query_parameters": {
"course_id": "169421928"
},
"request_content_type": null,
"response_status": 200,
"response_status_text": "OK",
"response_body": "[\n {\n \"id\": 91231435,\n \"name\": \"MyString\",\n \"crn\": \"MyString\",\n \"section_type\": \"MyString\",\n \"title\": \"MyString\",\n \"instructor\": \"MyString\",\n \"start_date\": \"2018-05-21\",\n \"end_date\": \"2018-06-04\",\n \"days\": \"MWF\",\n \"start_time\": \"12:00 pm\",\n \"end_time\": \"1:00 pm\",\n \"location\": \"MyString\",\n \"status\": \"MyString\",\n \"campus\": \"MyString\",\n \"notes\": \"MyString\",\n \"size_limit\": 1,\n \"course_id\": 169421928,\n \"created_at\": \"2018-09-02T18:29:10.904Z\",\n \"updated_at\": \"2018-09-02T18:29:10.904Z\"\n },\n {\n \"id\": 477709683,\n \"name\": \"MyString2\",\n \"crn\": \"MyString2\",\n \"section_type\": \"MyString\",\n \"title\": \"MyString\",\n \"instructor\": \"MyString\",\n \"start_date\": \"2018-05-21\",\n \"end_date\": \"2018-06-04\",\n \"days\": \"TR\",\n \"start_time\": \"11:00 am\",\n \"end_time\": \"2:00 pm\",\n \"location\": \"MyString\",\n \"status\": \"MyString\",\n \"campus\": \"MyString\",\n \"notes\": \"MyString\",\n \"size_limit\": 1,\n \"course_id\": 169421928,\n \"created_at\": \"2018-09-02T18:29:10.904Z\",\n \"updated_at\": \"2018-09-02T18:29:10.904Z\"\n }\n]",
"response_headers": {
},
"response_content_type": "application/json; charset=utf-8",
"curl": null
}
]
}
\ No newline at end of file
{
"resource": "Course Sections",
"resource_explanation": "A way to search across the different course sections (i.e. CS 112 001, ECON 103 104) for each course",
"http_method": "GET",
"route": "/api/course_sections",
"description": "Search by CRN",
"explanation": null,
"parameters": [
{
"type": "number",
"name": "course_id",
"description": " course"
},
{
"type": "string",
"name": "crn",
"description": " crn"
}
],
"response_fields": [
],
"requests": [
{
"request_method": "GET",
"request_path": "/api/course_sections?course_id=169421928&crn=70125",
"request_body": null,
"request_headers": {
},
"request_query_parameters": {
"course_id": "169421928",
"crn": "70125"
},
"request_content_type": null,
"response_status": 200,
"response_status_text": "OK",
"response_body": "[\n\n]",
"response_headers": {
},
"response_content_type": "application/json; charset=utf-8",
"curl": null
}
]
}
\ No newline at end of file
{
"resource": "Courses",
"resource_explanation": "A way to search across the different courses (i.e. CS 112, ECON 103) offered at GMU.",
"http_method": "GET",
"route": "/api/courses",
"description": "Filtered list of courses",
"explanation": null,
"parameters": [
{
"type": "string",
"name": "subject",
"description": " subject"
},
{
"type": "number",
"name": "course_number",
"description": " course number"
}
],
"response_fields": [
],
"requests": [
{
"request_method": "GET",
"request_path": "/api/courses?subject=CS&course_number=112",
"request_body": null,
"request_headers": {
},
"request_query_parameters": {
"subject": "CS",
"course_number": "112"
},
"request_content_type": null,
"response_status": 200,
"response_status_text": "OK",
"response_body": "[\n {\n \"id\": 169421928,\n \"subject\": \"CS\",\n \"course_number\": \"112\",\n \"semester_id\": 763694850,\n \"created_at\": \"2018-09-02T18:29:10.916Z\",\n \"updated_at\": \"2018-09-02T18:29:10.916Z\"\n }\n]",
"response_headers": {
},
"response_content_type": "application/json; charset=utf-8",
"curl": null
}
]
}
\ No newline at end of file
{
"resource": "Courses",
"resource_explanation": "A way to search across the different courses (i.e. CS 112, ECON 103) offered at GMU.",
"http_method": "GET",
"route": "/api/courses",
"description": "Listing all courses",
"explanation": null,
"parameters": [
],
"response_fields": [
],
"requests": [
{
"request_method": "GET",
"request_path": "/api/courses",
"request_body": null,
"request_headers": {
},
"request_query_parameters": {
},
"request_content_type": null,
"response_status": 200,
"response_status_text": "OK",
"response_body": "[\n {\n \"id\": 19883831,\n \"subject\": \"ACCT\",\n \"course_number\": \"110\",\n \"semester_id\": 938910979,\n \"created_at\": \"2018-09-02T18:29:10.916Z\",\n \"updated_at\": \"2018-09-02T18:29:10.916Z\"\n },\n {\n \"id\": 169421928,\n \"subject\": \"CS\",\n \"course_number\": \"112\",\n \"semester_id\": 763694850,\n \"created_at\": \"2018-09-02T18:29:10.916Z\",\n \"updated_at\": \"2018-09-02T18:29:10.916Z\"\n },\n {\n \"id\": 290898823,\n \"subject\": \"CS\",\n \"course_number\": \"211\",\n \"semester_id\": 763694850,\n \"created_at\": \"2018-09-02T18:29:10.916Z\",\n \"updated_at\": \"2018-09-02T18:29:10.916Z\"\n },\n {\n \"id\": 605506893,\n \"subject\": \"CS\",\n \"course_number\": \"110\",\n \"semester_id\": 938910979,\n \"created_at\": \"2018-09-02T18:29:10.916Z\",\n \"updated_at\": \"2018-09-02T18:29:10.916Z\"\n }\n]",
"response_headers": {
},
"response_content_type": "application/json; charset=utf-8",
"curl": null
}
]
}
\ No newline at end of file
{
"resources": [
{
"name": "Course Sections",
"explanation": "A way to search across the different course sections (i.e. CS 112 001, ECON 103 104) for each course",
"examples": [
{
"description": "Search by CRN",
"link": "course_sections/search_by_crn.json",
"groups": "all",
"route": "/api/course_sections",
"method": "get"
},
{
"description": "Search by course",
"link": "course_sections/search_by_course.json",
"groups": "all",
"route": "/api/course_sections",
"method": "get"
}
]
},
{
"name": "Courses",
"explanation": "A way to search across the different courses (i.e. CS 112, ECON 103) offered at GMU.",
"examples": [
{
"description": "Filtered list of courses",
"link": "courses/filtered_list_of_courses.json",
"groups": "all",
"route": "/api/courses",
"method": "get"
},
{
"description": "Listing all courses",
"link": "courses/listing_all_courses.json",
"groups": "all",
"route": "/api/courses",
"method": "get"
}
]
}
]
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
require 'rails_helper'
require 'rspec_api_documentation/dsl'
resource "Course Sections" do
explanation "A way to search across the different course sections (i.e. CS 112 001, ECON 103 104) for each course"
get "/api/course_sections" do
parameter :course_id, type: :number
parameter :crn, type: :string
context '200' do
let(:course_id) { 169421928 }
let(:crn) { "70125" }
example_request 'Search by CRN' do
expect(status).to eq(200)
end
end
context '200' do
let(:course_id) { 169421928 }
example_request 'Search by course' do
expect(status).to eq(200)
end
end
end
end
require 'rails_helper'
require 'rspec_api_documentation/dsl'
resource "Courses" do
explanation "A way to search across the different courses (i.e. CS 112, ECON 103) offered at GMU."
get "/api/courses" do
context '200' do
parameter :subject, type: :string
parameter :course_number, type: :number
let(:subject) { 'CS' }
let(:course_number) { 112 }
example_request 'Filtered list of courses' do
expect(status).to eq(200)
end
end
context '200' do
example_request 'Listing all courses' do
expect(status).to eq(200)
end
end
end
end
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
end
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
# this file to always be loaded, without a need to explicitly require it in any
# files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need
# it.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`