school_loop 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +91 -0
- data/LICENSE +19 -0
- data/README.md +106 -0
- data/Rakefile +6 -0
- data/lib/school_loop.rb +25 -0
- data/lib/school_loop/client.rb +39 -0
- data/lib/school_loop/configuration.rb +54 -0
- data/lib/school_loop/connection.rb +28 -0
- data/lib/school_loop/error.rb +16 -0
- data/lib/school_loop/error/bad_request.rb +12 -0
- data/lib/school_loop/error/service_error.rb +22 -0
- data/lib/school_loop/error/unauthorized.rb +12 -0
- data/lib/school_loop/resources.rb +8 -0
- data/lib/school_loop/resources/progress_reports.rb +15 -0
- data/lib/school_loop/resources/roster.rb +18 -0
- data/lib/school_loop/response.rb +20 -0
- data/lib/school_loop/response/raise_error.rb +21 -0
- data/lib/school_loop/response/xmlize.rb +28 -0
- data/lib/school_loop/version.rb +3 -0
- data/school_loop.gemspec +27 -0
- data/spec/fixtures/progress_report_submission.xml +33 -0
- data/spec/fixtures/roster_response.xml +50 -0
- data/spec/helper.rb +28 -0
- data/spec/school_loop/client_spec.rb +84 -0
- data/spec/school_loop/configuration_spec.rb +41 -0
- data/spec/school_loop/resources/progress_reports_spec.rb +39 -0
- data/spec/school_loop/resources/roster_spec.rb +41 -0
- data/spec/school_loop/response/xmlize_spec.rb +0 -0
- data/spec/school_loop_spec.rb +64 -0
- metadata +143 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 07ac5da7b48f65a5d323294763459397ec01ebe6
         | 
| 4 | 
            +
              data.tar.gz: c019c80fbdc560ac6810f163d251e8a6e6d76dc0
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: b41f0caca0c1850d4ccc4415265d91fd6084e1cf51873fb8a5205991fdb31ceced125b83a75780333fcab1534314715a5accf87f96d3de781edf8afa7b55ab56
         | 
| 7 | 
            +
              data.tar.gz: b6d0ed1e89c2aa21318afc7dc45c9a55f2bf9f9201ae296ed01c5f6edcad02f5f8d08649e2e83954307a0457925c3cf228a961a7b911d7851970c3c46d978153
         | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            --color
         | 
    
        data/.ruby-version
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            2.2.0
         | 
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            PATH
         | 
| 2 | 
            +
              remote: .
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                school_loop (0.0.1)
         | 
| 5 | 
            +
                  faraday (~> 0.9)
         | 
| 6 | 
            +
                  faraday_middleware (~> 0.9)
         | 
| 7 | 
            +
                  nokogiri (>= 1.5.2)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            GEM
         | 
| 10 | 
            +
              remote: https://www.rubygems.org/
         | 
| 11 | 
            +
              specs:
         | 
| 12 | 
            +
                addressable (2.3.8)
         | 
| 13 | 
            +
                coderay (1.1.0)
         | 
| 14 | 
            +
                coveralls (0.8.2)
         | 
| 15 | 
            +
                  json (~> 1.8)
         | 
| 16 | 
            +
                  rest-client (>= 1.6.8, < 2)
         | 
| 17 | 
            +
                  simplecov (~> 0.10.0)
         | 
| 18 | 
            +
                  term-ansicolor (~> 1.3)
         | 
| 19 | 
            +
                  thor (~> 0.19.1)
         | 
| 20 | 
            +
                crack (0.4.2)
         | 
| 21 | 
            +
                  safe_yaml (~> 1.0.0)
         | 
| 22 | 
            +
                diff-lcs (1.2.5)
         | 
| 23 | 
            +
                docile (1.1.5)
         | 
| 24 | 
            +
                domain_name (0.5.24)
         | 
| 25 | 
            +
                  unf (>= 0.0.5, < 1.0.0)
         | 
| 26 | 
            +
                faraday (0.9.1)
         | 
| 27 | 
            +
                  multipart-post (>= 1.2, < 3)
         | 
| 28 | 
            +
                faraday_middleware (0.10.0)
         | 
| 29 | 
            +
                  faraday (>= 0.7.4, < 0.10)
         | 
| 30 | 
            +
                http-cookie (1.0.2)
         | 
| 31 | 
            +
                  domain_name (~> 0.5)
         | 
| 32 | 
            +
                json (1.8.3)
         | 
| 33 | 
            +
                method_source (0.8.2)
         | 
| 34 | 
            +
                mime-types (1.25.1)
         | 
| 35 | 
            +
                mini_portile (0.6.2)
         | 
| 36 | 
            +
                multipart-post (2.0.0)
         | 
| 37 | 
            +
                netrc (0.10.3)
         | 
| 38 | 
            +
                nokogiri (1.6.6.2)
         | 
| 39 | 
            +
                  mini_portile (~> 0.6.0)
         | 
| 40 | 
            +
                pry (0.10.1)
         | 
| 41 | 
            +
                  coderay (~> 1.1.0)
         | 
| 42 | 
            +
                  method_source (~> 0.8.1)
         | 
| 43 | 
            +
                  slop (~> 3.4)
         | 
| 44 | 
            +
                rake (10.4.2)
         | 
| 45 | 
            +
                rest-client (1.8.0)
         | 
| 46 | 
            +
                  http-cookie (>= 1.0.2, < 2.0)
         | 
| 47 | 
            +
                  mime-types (>= 1.16, < 3.0)
         | 
| 48 | 
            +
                  netrc (~> 0.7)
         | 
| 49 | 
            +
                rspec (3.3.0)
         | 
| 50 | 
            +
                  rspec-core (~> 3.3.0)
         | 
| 51 | 
            +
                  rspec-expectations (~> 3.3.0)
         | 
| 52 | 
            +
                  rspec-mocks (~> 3.3.0)
         | 
| 53 | 
            +
                rspec-core (3.3.2)
         | 
| 54 | 
            +
                  rspec-support (~> 3.3.0)
         | 
| 55 | 
            +
                rspec-expectations (3.3.1)
         | 
| 56 | 
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 57 | 
            +
                  rspec-support (~> 3.3.0)
         | 
| 58 | 
            +
                rspec-mocks (3.3.2)
         | 
| 59 | 
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 60 | 
            +
                  rspec-support (~> 3.3.0)
         | 
| 61 | 
            +
                rspec-support (3.3.0)
         | 
| 62 | 
            +
                safe_yaml (1.0.4)
         | 
| 63 | 
            +
                simplecov (0.10.0)
         | 
| 64 | 
            +
                  docile (~> 1.1.0)
         | 
| 65 | 
            +
                  json (~> 1.8)
         | 
| 66 | 
            +
                  simplecov-html (~> 0.10.0)
         | 
| 67 | 
            +
                simplecov-html (0.10.0)
         | 
| 68 | 
            +
                slop (3.6.0)
         | 
| 69 | 
            +
                term-ansicolor (1.3.2)
         | 
| 70 | 
            +
                  tins (~> 1.0)
         | 
| 71 | 
            +
                thor (0.19.1)
         | 
| 72 | 
            +
                tins (1.5.4)
         | 
| 73 | 
            +
                unf (0.1.4)
         | 
| 74 | 
            +
                  unf_ext
         | 
| 75 | 
            +
                unf_ext (0.0.7.1)
         | 
| 76 | 
            +
                webmock (1.21.0)
         | 
| 77 | 
            +
                  addressable (>= 2.3.6)
         | 
| 78 | 
            +
                  crack (>= 0.3.2)
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            PLATFORMS
         | 
| 81 | 
            +
              ruby
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            DEPENDENCIES
         | 
| 84 | 
            +
              bundler (~> 1.0)
         | 
| 85 | 
            +
              coveralls
         | 
| 86 | 
            +
              pry
         | 
| 87 | 
            +
              rake
         | 
| 88 | 
            +
              rspec (~> 3.3)
         | 
| 89 | 
            +
              school_loop!
         | 
| 90 | 
            +
              simplecov
         | 
| 91 | 
            +
              webmock (>= 1.9)
         | 
    
        data/LICENSE
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            Copyright (c) 2015 Mitch Dempsey
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 4 | 
            +
            of this software and associated documentation files (the "Software"), to deal
         | 
| 5 | 
            +
            in the Software without restriction, including without limitation the rights
         | 
| 6 | 
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         | 
| 7 | 
            +
            copies of the Software, and to permit persons to whom the Software is
         | 
| 8 | 
            +
            furnished to do so, subject to the following conditions:
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            The above copyright notice and this permission notice shall be included in
         | 
| 11 | 
            +
            all copies or substantial portions of the Software.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         | 
| 14 | 
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         | 
| 15 | 
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         | 
| 16 | 
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         | 
| 17 | 
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         | 
| 18 | 
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         | 
| 19 | 
            +
            THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            # School Loop API
         | 
| 2 | 
            +
             | 
| 3 | 
            +
             | 
| 4 | 
            +
            [](https://travis-ci.org/webdestroya/school_loop)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## Installation
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Install the gem by issuing
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ```ruby
         | 
| 12 | 
            +
            gem install school_loop
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            or put it in your Gemfile and run `bundle install`
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ```ruby
         | 
| 18 | 
            +
            gem "school_loop"
         | 
| 19 | 
            +
            ```
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            ## Configuration
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            These global settings will be used unless specifically overridden by an instance below.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            ```ruby
         | 
| 26 | 
            +
            SchoolLoop.configure do |config|
         | 
| 27 | 
            +
              config.subdomain  = 'demoschool'
         | 
| 28 | 
            +
              config.username   = 'apiuser'
         | 
| 29 | 
            +
              config.password   = 'some_api_password'
         | 
| 30 | 
            +
              config.adapter    = :net_http
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
            ```
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ## Usage
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            Create a new client using the global defaults:
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            ```ruby
         | 
| 39 | 
            +
            school_loop = SchoolLoop.new
         | 
| 40 | 
            +
            ```
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            Create a new client instance and override global defaults
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            ```ruby
         | 
| 45 | 
            +
            school_loop = SchoolLoop.new subdomain: 'demoschool', username: 'apiuser', password: 'some_api_password'
         | 
| 46 | 
            +
            ```
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            Alternatively, you can configure the School Loop settings by passing a block:
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            ```ruby
         | 
| 51 | 
            +
            school_loop = SchoolLoop.new do |config|
         | 
| 52 | 
            +
              config.subdomain  = 'demoschool'
         | 
| 53 | 
            +
              config.username   = 'apiuser'
         | 
| 54 | 
            +
              config.password   = 'some_api_password'
         | 
| 55 | 
            +
              config.adapter    = :net_http
         | 
| 56 | 
            +
            end
         | 
| 57 | 
            +
            ```
         | 
| 58 | 
            +
             | 
| 59 | 
            +
             | 
| 60 | 
            +
            Currently, only three methods are implemented:
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            #### Get Entire School Roster
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            ```ruby
         | 
| 65 | 
            +
            roster = school_loop.get_roster
         | 
| 66 | 
            +
            # returns a Nokogiri::XML::Document
         | 
| 67 | 
            +
            ```
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            #### Get Teacher Roster
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            ```ruby
         | 
| 72 | 
            +
            teacher_id = "12345"
         | 
| 73 | 
            +
            roster = school_loop.get_roster(teacher_id)
         | 
| 74 | 
            +
            # returns a Nokogiri::XML::Document (with a single 'teacher' node)
         | 
| 75 | 
            +
            ```
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            Example roster data is available on [School Loop's Documentation](http://www.schoolloop.com/about-us/partners/progress-report-api/progress-report-api-schema/#ProgressReportSchema-IVSampleSchoolLoopRosterDownload)
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            #### Posting Progress Reports
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            For a detailed schema for Progress reports, you can look at [School Loop's Progress Report API Schema](http://www.schoolloop.com/about-us/partners/progress-report-api/progress-report-api-schema/)
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            ```ruby
         | 
| 84 | 
            +
            prog_report_xml = <<-EOF
         | 
| 85 | 
            +
            <?xml version="1.0" encoding="UTF-8"?>
         | 
| 86 | 
            +
            <root>
         | 
| 87 | 
            +
              <sections>
         | 
| 88 | 
            +
                <section ID="1234">
         | 
| 89 | 
            +
                  <progressReports>
         | 
| 90 | 
            +
                    <progressReport markName="Current Grades" ... grade="A">
         | 
| 91 | 
            +
                      ...
         | 
| 92 | 
            +
                    </progressReport>
         | 
| 93 | 
            +
                  </progressReports>
         | 
| 94 | 
            +
                </section>
         | 
| 95 | 
            +
              </sections>
         | 
| 96 | 
            +
            </root>
         | 
| 97 | 
            +
            EOF
         | 
| 98 | 
            +
             | 
| 99 | 
            +
            school_loop.publish_progress_report(prog_report_xml)
         | 
| 100 | 
            +
            ```
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            ## License
         | 
| 103 | 
            +
            [MIT](http://opensource.org/licenses/MIT)
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            ## Special Thanks
         | 
| 106 | 
            +
            This gem is heavily based on the [bitbucket_rest_api](https://github.com/vongrippen/bitbucket) gem by Mike Cochran.
         | 
    
        data/Rakefile
    ADDED
    
    
    
        data/lib/school_loop.rb
    ADDED
    
    | @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            require 'school_loop/version'
         | 
| 2 | 
            +
            require 'school_loop/configuration'
         | 
| 3 | 
            +
            require 'school_loop/connection'
         | 
| 4 | 
            +
            require 'school_loop/client'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module SchoolLoop
         | 
| 7 | 
            +
              extend Configuration
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              class << self
         | 
| 10 | 
            +
                def new(options = {}, &block)
         | 
| 11 | 
            +
                  SchoolLoop::Client.new(options, &block)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def method_missing(method, *args, &block)
         | 
| 15 | 
            +
                  return super unless new.respond_to?(method)
         | 
| 16 | 
            +
                  new.send(method, *args, &block)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def respond_to?(method, include_private = false)
         | 
| 20 | 
            +
                  new.respond_to?(method, include_private) || super(method, include_private)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
             | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require 'school_loop/configuration'
         | 
| 2 | 
            +
            require 'school_loop/connection'
         | 
| 3 | 
            +
            require 'school_loop/resources'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module SchoolLoop
         | 
| 6 | 
            +
              class Client
         | 
| 7 | 
            +
                include Connection
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                include Resources::ProgressReports
         | 
| 10 | 
            +
                include Resources::Roster
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                attr_reader *Configuration::VALID_OPTIONS_KEYS
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # Callback to update global configuration options
         | 
| 15 | 
            +
                class_eval do
         | 
| 16 | 
            +
                  Configuration::VALID_OPTIONS_KEYS.each do |key|
         | 
| 17 | 
            +
                    define_method "#{key}=" do |arg|
         | 
| 18 | 
            +
                      self.instance_variable_set("@#{key}", arg)
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                # Creates new API
         | 
| 24 | 
            +
                def initialize(options={}, &block)
         | 
| 25 | 
            +
                  super()
         | 
| 26 | 
            +
                  setup options
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  self.instance_eval(&block) if block_given?
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def setup(options={})
         | 
| 32 | 
            +
                  options = SchoolLoop.options.merge(options)
         | 
| 33 | 
            +
                  Configuration::VALID_OPTIONS_KEYS.each do |key|
         | 
| 34 | 
            +
                    send("#{key}=", options[key])
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            module SchoolLoop
         | 
| 2 | 
            +
              module Configuration
         | 
| 3 | 
            +
                VALID_OPTIONS_KEYS = [
         | 
| 4 | 
            +
                  :username,
         | 
| 5 | 
            +
                  :password,
         | 
| 6 | 
            +
                  :subdomain,
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  :secure,
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  :adapter,
         | 
| 11 | 
            +
                  :user_agent,
         | 
| 12 | 
            +
                  :connection_options,
         | 
| 13 | 
            +
                  :debug,
         | 
| 14 | 
            +
                ].freeze
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                DEFAULT_ADAPTER = :net_http
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                DEFAULT_USERNAME = nil
         | 
| 19 | 
            +
                DEFAULT_PASSWORD = nil
         | 
| 20 | 
            +
                DEFAULT_SUBDOMAIN = nil
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                DEFAULT_USER_AGENT = "School Loop Ruby API v#{SchoolLoop::VERSION}".freeze
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                DEFAULT_CONNECTION_OPTIONS = {}
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                attr_accessor *VALID_OPTIONS_KEYS
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def configure
         | 
| 29 | 
            +
                  yield self
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def self.extended(base)
         | 
| 33 | 
            +
                  base.set_defaults
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def options
         | 
| 37 | 
            +
                  options = { }
         | 
| 38 | 
            +
                  VALID_OPTIONS_KEYS.each { |k| options[k] = send(k) }
         | 
| 39 | 
            +
                  options
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def set_defaults
         | 
| 43 | 
            +
                  self.adapter            = DEFAULT_ADAPTER
         | 
| 44 | 
            +
                  self.user_agent         = DEFAULT_USER_AGENT
         | 
| 45 | 
            +
                  self.connection_options = DEFAULT_CONNECTION_OPTIONS
         | 
| 46 | 
            +
                  self.username           = DEFAULT_USERNAME
         | 
| 47 | 
            +
                  self.subdomain          = DEFAULT_SUBDOMAIN
         | 
| 48 | 
            +
                  self.password           = DEFAULT_PASSWORD
         | 
| 49 | 
            +
                  self.secure             = true
         | 
| 50 | 
            +
                  self.debug              = false
         | 
| 51 | 
            +
                  self
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            require 'faraday'
         | 
| 2 | 
            +
            require 'faraday_middleware'
         | 
| 3 | 
            +
            require 'school_loop/response'
         | 
| 4 | 
            +
            require 'school_loop/response/raise_error'
         | 
| 5 | 
            +
            require 'school_loop/response/xmlize'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module SchoolLoop
         | 
| 8 | 
            +
              module Connection
         | 
| 9 | 
            +
                extend self
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
                def connection
         | 
| 13 | 
            +
                  @connection ||= Faraday.new({url: "#{secure ? 'https' : 'http'}://#{subdomain}.schoolloop.com"}.merge(connection_options)) do |faraday|
         | 
| 14 | 
            +
                    faraday.request :basic_auth, username, password
         | 
| 15 | 
            +
                    faraday.headers[:user_agent] = user_agent
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    if debug
         | 
| 18 | 
            +
                      faraday.response :logger
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    faraday.use SchoolLoop::Response::Xmlize,  :content_type => /\bxml$/
         | 
| 22 | 
            +
                    faraday.use SchoolLoop::Response::RaiseError
         | 
| 23 | 
            +
                    faraday.adapter adapter
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module SchoolLoop
         | 
| 2 | 
            +
              module Error
         | 
| 3 | 
            +
                class SchoolLoopError < StandardError
         | 
| 4 | 
            +
                  attr_reader :response_message, :response_headers
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(message)
         | 
| 7 | 
            +
                    super message
         | 
| 8 | 
            +
                    @response_message = message
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            require "school_loop/error/service_error"
         | 
| 15 | 
            +
            require "school_loop/error/bad_request"
         | 
| 16 | 
            +
            require "school_loop/error/unauthorized"
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module SchoolLoop #:nodoc
         | 
| 4 | 
            +
              # Raised when SchoolLoop returns any of the HTTP status codes
         | 
| 5 | 
            +
              module Error
         | 
| 6 | 
            +
                class ServiceError < SchoolLoopError
         | 
| 7 | 
            +
                  attr_accessor :http_headers, :http_status, :http_method, :url
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def initialize(env)
         | 
| 10 | 
            +
                    super(generate_message(env))
         | 
| 11 | 
            +
                    @http_headers = env[:response_headers]
         | 
| 12 | 
            +
                    @http_status = env[:status]
         | 
| 13 | 
            +
                    @http_method = env[:method].to_s.upcase
         | 
| 14 | 
            +
                    @url = env[:url].to_s
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def generate_message(env)
         | 
| 18 | 
            +
                    "#{env[:body]}"
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end # Error
         | 
| 22 | 
            +
            end # SchoolLoop
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            module SchoolLoop
         | 
| 2 | 
            +
              module Resources
         | 
| 3 | 
            +
                module ProgressReports
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  def publish_progress_report(xml_body)
         | 
| 6 | 
            +
                    connection.post do |req|
         | 
| 7 | 
            +
                      req.url "/api/progressReports"
         | 
| 8 | 
            +
                      req.headers['Content-Type'] = "application/xml"
         | 
| 9 | 
            +
                      req.body = xml_body
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module SchoolLoop
         | 
| 2 | 
            +
              module Resources
         | 
| 3 | 
            +
                module Roster
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Get the roster for all teachers, or limit to a specific teacher
         | 
| 6 | 
            +
                  def get_roster(teacher_id = nil)
         | 
| 7 | 
            +
                    connection.get do |req|
         | 
| 8 | 
            +
                      req.url "/api/roster"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                      if teacher_id
         | 
| 11 | 
            +
                        req.params['teacher_id'] = teacher_id
         | 
| 12 | 
            +
                      end
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            require 'faraday'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module SchoolLoop
         | 
| 5 | 
            +
              class Response < Faraday::Response::Middleware
         | 
| 6 | 
            +
                CONTENT_TYPE = 'Content-Type'.freeze
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                class << self
         | 
| 9 | 
            +
                  attr_accessor :parser
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.define_parser(&block)
         | 
| 13 | 
            +
                  @parser = block
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def response_type(env)
         | 
| 17 | 
            +
                  env[:response_headers][CONTENT_TYPE].to_s
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'faraday'
         | 
| 4 | 
            +
            require 'school_loop/error'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module SchoolLoop
         | 
| 7 | 
            +
              class Response::RaiseError < Faraday::Response::Middleware
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def on_complete(env)
         | 
| 10 | 
            +
                  case env[:status].to_i
         | 
| 11 | 
            +
                  when 400
         | 
| 12 | 
            +
                    raise SchoolLoop::Error::BadRequest.new(env)
         | 
| 13 | 
            +
                  when 401
         | 
| 14 | 
            +
                    raise SchoolLoop::Error::Unauthorized.new(env)
         | 
| 15 | 
            +
                  when 400...600
         | 
| 16 | 
            +
                    raise SchoolLoop::Error::ServiceError.new(env)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              end # Response::RaiseError
         | 
| 21 | 
            +
            end # SchoolLoop
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'faraday'
         | 
| 4 | 
            +
            require 'faraday_middleware'
         | 
| 5 | 
            +
            require 'faraday_middleware/response_middleware'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module SchoolLoop
         | 
| 8 | 
            +
              class Response::Xmlize < ::FaradayMiddleware::ResponseMiddleware
         | 
| 9 | 
            +
                dependency 'nokogiri'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                define_parser do |body|
         | 
| 12 | 
            +
                  ::Nokogiri::XML body
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def parse(body)
         | 
| 16 | 
            +
                  case body
         | 
| 17 | 
            +
                  when ''
         | 
| 18 | 
            +
                    nil
         | 
| 19 | 
            +
                  when 'true'
         | 
| 20 | 
            +
                    true
         | 
| 21 | 
            +
                  when 'false'
         | 
| 22 | 
            +
                    false
         | 
| 23 | 
            +
                  else
         | 
| 24 | 
            +
                    self.class.parser.call body
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end # Response::Xmlize
         | 
| 28 | 
            +
            end # SchoolLoop
         | 
    
        data/school_loop.gemspec
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 3 | 
            +
            require 'school_loop/version'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |spec|
         | 
| 6 | 
            +
              spec.name        = "school_loop"
         | 
| 7 | 
            +
              spec.version     = SchoolLoop::VERSION
         | 
| 8 | 
            +
              spec.platform    = Gem::Platform::RUBY
         | 
| 9 | 
            +
              spec.authors     = ['Mitch Dempsey']
         | 
| 10 | 
            +
              spec.email       = ['mitch@mitchdempsey.com']
         | 
| 11 | 
            +
              spec.licenses    = ['MIT']
         | 
| 12 | 
            +
              spec.homepage    = "https://github.com/webdestroya/school_loop"
         | 
| 13 | 
            +
              spec.summary     = "Client for School Loop API (OpenLoop)"
         | 
| 14 | 
            +
              spec.description = "Client for School Loop API (OpenLoop)"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              spec.files         = `git ls-files`.split("\n")
         | 
| 17 | 
            +
              spec.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 18 | 
            +
              spec.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 19 | 
            +
              spec.require_paths = ["lib"]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              spec.add_development_dependency 'bundler', '~> 1.0'
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              spec.add_dependency 'faraday', '~> 0.9'
         | 
| 24 | 
            +
              spec.add_dependency 'faraday_middleware', '~> 0.9'
         | 
| 25 | 
            +
              #spec.add_dependency 'ox', '~> 2.2.1'
         | 
| 26 | 
            +
              spec.add_dependency 'nokogiri', '>= 1.5.2'
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            <?xml version="1.0" encoding="UTF-8"?>
         | 
| 2 | 
            +
            <root>
         | 
| 3 | 
            +
                <sections>
         | 
| 4 | 
            +
                    <section ID="1234">
         | 
| 5 | 
            +
                        <progressReports>
         | 
| 6 | 
            +
                            <progressReport markName="Current Grades" date="2007-08-12T22:24:15Z" score="0.95" grade="A" hasScore="true" useWeighting="false" gradebookDate="">
         | 
| 7 | 
            +
                                <gradeDefinitions>
         | 
| 8 | 
            +
                                    <keyValue key="INC" value="INCOMPLETE (not handed in)"/>
         | 
| 9 | 
            +
                                </gradeDefinitions>
         | 
| 10 | 
            +
                                <categories>
         | 
| 11 | 
            +
                                    <category hasScore="true" name="Assignment" weight="-1.000" score="0.000"/>
         | 
| 12 | 
            +
                                </categories>
         | 
| 13 | 
            +
                                <course period="3" systemID="100000881299" name="English"/>
         | 
| 14 | 
            +
                                <gradingScale>
         | 
| 15 | 
            +
                                    <cutoffs>
         | 
| 16 | 
            +
                                        <cutoff Start="90" Name="A"/>
         | 
| 17 | 
            +
                                        <cutoff Start="0" Name="F"/>
         | 
| 18 | 
            +
                                    </cutoffs>
         | 
| 19 | 
            +
                                </gradingScale>
         | 
| 20 | 
            +
                                <grades>
         | 
| 21 | 
            +
                                    <grade score="10" excused="false" comment="" grade="B">
         | 
| 22 | 
            +
                                        <assignment categoryName="Assignment" maxPoints="10" dueDate="2007-05-18T00:00:00Z" title="WWI"/>
         | 
| 23 | 
            +
                                    </grade>
         | 
| 24 | 
            +
                                    <grade score="10" excused="false" comment="" grade="B">
         | 
| 25 | 
            +
                                        <assignment categoryName="Assignment" maxPoints="10" dueDate="2007-05-18T00:00:00Z" title="Thing 2"/>
         | 
| 26 | 
            +
                                    </grade>
         | 
| 27 | 
            +
                                </grades>
         | 
| 28 | 
            +
                                <student name="Cleaver, Kevin" schoolID="7123456"/>
         | 
| 29 | 
            +
                            </progressReport>
         | 
| 30 | 
            +
                        </progressReports>
         | 
| 31 | 
            +
                    </section>
         | 
| 32 | 
            +
                </sections>
         | 
| 33 | 
            +
            </root>
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            <?xml version="1.0" encoding="UTF-8"?>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <root>
         | 
| 4 | 
            +
              <roster source="schoolloop.com">
         | 
| 5 | 
            +
                <teachers>
         | 
| 6 | 
            +
                  <teacher systemID="1111180131503" localID="111111" name="Reynolds, Mr. Malcom">
         | 
| 7 | 
            +
                    <courses>
         | 
| 8 | 
            +
                      <course systemID="1111107012313" name="Math">
         | 
| 9 | 
            +
                        <periods>
         | 
| 10 | 
            +
                          <period systemID="1111133312598" number="1">
         | 
| 11 | 
            +
                            <assignments/>
         | 
| 12 | 
            +
                            <students>
         | 
| 13 | 
            +
                              <student permID="1000265" systemID="1111170083336" gradeLevel="12" firstName="Ryan" middleName="Chris" lastName="Test" displayID="1000265" localID="1234" sectionID="1234" sectionSystemID="1111133311259"/>
         | 
| 14 | 
            +
                              <student permID="1000186" systemID="1111170083213" gradeLevel="11" firstName="Manuel" middleName="" lastName="Test" displayID="1000186" localID="5677" sectionID="1234" sectionSystemID="1111133311259"/>
         | 
| 15 | 
            +
                              <student permID="1000673" systemID="1111170083137" gradeLevel="11" firstName="Justin" middleName="" lastName="Test" displayID="1000673" localID="8900" sectionID="1234" sectionSystemID="1111133311259"/>
         | 
| 16 | 
            +
                              <student permID="1000878" systemID="1111170082883" gradeLevel="11" firstName="Dave" middleName="" lastName="Test" displayID="1000878" localID="1235" sectionID="1234" sectionSystemID="1111133311259"/>
         | 
| 17 | 
            +
                              <student permID="1000985" systemID="1111107494444" gradeLevel="12" firstName="Colby" middleName="Jeffrey" lastName="Test" displayID="1000985" localID="1236" sectionID="1234" sectionSystemID="1111133311259"/>
         | 
| 18 | 
            +
                            </students>
         | 
| 19 | 
            +
                          </period>
         | 
| 20 | 
            +
                        </periods>
         | 
| 21 | 
            +
                      </course>
         | 
| 22 | 
            +
                      <course systemID="1111107012069" name="English 3">
         | 
| 23 | 
            +
                        <periods>
         | 
| 24 | 
            +
                          <period systemID="1111133312700" number="5">
         | 
| 25 | 
            +
                            <assignments>
         | 
| 26 | 
            +
                              <assignment dueDate="2015-08-27T00:00:00Z" maxPoints="10.0" systemID="1111143710574" categoryName="Assignment" title="Parent Signature" categoryID="1111146128059"/>
         | 
| 27 | 
            +
                              <assignment dueDate="2015-09-10T00:00:00Z" maxPoints="42.0" systemID="1111124172130" categoryName="Assignment" title="Unit 1 Literary Terms Worksheet and Test" categoryID="1111146128059"/>
         | 
| 28 | 
            +
                              <assignment dueDate="2015-10-02T00:00:00Z" maxPoints="100.0" systemID="1111124171925" categoryName="Assignment" title="Participation/Professionalism" categoryID="1111146128059"/>
         | 
| 29 | 
            +
                            </assignments>
         | 
| 30 | 
            +
                            <students>
         | 
| 31 | 
            +
                              <student permID="1000338" systemID="1111170083144" gradeLevel="11" firstName="Henny" middleName="" lastName="Test" displayID="1000338" localID="123" sectionID="1000" sectionSystemID="1111133311919"/>
         | 
| 32 | 
            +
                              <student permID="1000997" systemID="1111170083020" gradeLevel="11" firstName="Sean" middleName="" lastName="Test" displayID="1000997" localID="456" sectionID="1000" sectionSystemID="1111133311919"/>
         | 
| 33 | 
            +
                              <student permID="1000673" systemID="1111170083137" gradeLevel="11" firstName="Justin" middleName="" lastName="Test" displayID="1000673" localID="789" sectionID="1000" sectionSystemID="1111133311919"/>
         | 
| 34 | 
            +
                              <student permID="1000828" systemID="1111143756226" gradeLevel="11" firstName="Fred" middleName="Adele" lastName="Test" displayID="1000828" localID="8456" sectionID="1000" sectionSystemID="1111133311919"/>
         | 
| 35 | 
            +
                              <student permID="1000977" systemID="1111170082757" gradeLevel="11" firstName="Peter" middleName="Jay" lastName="Test" displayID="1000977" localID="9456" sectionID="1000" sectionSystemID="1111133311919"/>
         | 
| 36 | 
            +
                              <student permID="1000183" systemID="1111170083015" gradeLevel="11" firstName="Kyle" middleName="Kend" lastName="Test" displayID="1000183" localID="7456" sectionID="1000" sectionSystemID="1111133311919"/>
         | 
| 37 | 
            +
                            </students>
         | 
| 38 | 
            +
                          </period>
         | 
| 39 | 
            +
                        </periods>
         | 
| 40 | 
            +
                      </course>
         | 
| 41 | 
            +
                    </courses>
         | 
| 42 | 
            +
                    <categories>
         | 
| 43 | 
            +
                      <category systemID="1111146879613" name="Classwork - Homework"/>
         | 
| 44 | 
            +
                      <category systemID="1111146128059" name="Assignment"/>
         | 
| 45 | 
            +
                      <category systemID="1111175461981" name="Quiz / Test"/>
         | 
| 46 | 
            +
                    </categories>
         | 
| 47 | 
            +
                  </teacher>
         | 
| 48 | 
            +
                </teachers>
         | 
| 49 | 
            +
              </roster>
         | 
| 50 | 
            +
            </root>
         | 
    
        data/spec/helper.rb
    ADDED
    
    | @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            if RUBY_ENGINE == 'ruby'
         | 
| 2 | 
            +
              require 'simplecov'
         | 
| 3 | 
            +
              require 'coveralls'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
         | 
| 6 | 
            +
                SimpleCov::Formatter::HTMLFormatter,
         | 
| 7 | 
            +
                Coveralls::SimpleCov::Formatter
         | 
| 8 | 
            +
              ]
         | 
| 9 | 
            +
              SimpleCov.start
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            require 'school_loop'
         | 
| 13 | 
            +
            require 'rspec'
         | 
| 14 | 
            +
            require 'webmock/rspec'
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            WebMock.disable_net_connect!(:allow => 'coveralls.io')
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            RSpec.configure do |config|
         | 
| 19 | 
            +
              config.raise_errors_for_deprecations!
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            def fixture_path
         | 
| 23 | 
            +
              File.expand_path("../fixtures", __FILE__)
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            def fixture(file)
         | 
| 27 | 
            +
              File.new(fixture_path + '/' + file)
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,84 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SchoolLoop::Client do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
             | 
| 7 | 
            +
             | 
| 8 | 
            +
              describe "error handling" do
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                let(:unauth_client) do
         | 
| 11 | 
            +
                  SchoolLoop.new do |config|
         | 
| 12 | 
            +
                    config.subdomain  = 'subdomain'
         | 
| 13 | 
            +
                    config.username   = 'username'
         | 
| 14 | 
            +
                    config.password   = 'password'
         | 
| 15 | 
            +
                    config.adapter    = :net_http
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # bad user, good password
         | 
| 20 | 
            +
                # 401 ERROR: Authorization failed: user or role not privileged.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # bad user, bad password
         | 
| 23 | 
            +
                # 401 ERROR: Authorization failed: password incorrect.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                # api not enabled
         | 
| 26 | 
            +
                # 400 Error: OpenLoop is not enabled for subdomain.schoolloop.com. Contact School Loop.
         | 
| 27 | 
            +
             | 
| 28 | 
            +
             | 
| 29 | 
            +
                context "401 Unauthorized" do
         | 
| 30 | 
            +
                  before(:each) do
         | 
| 31 | 
            +
                    stub_request(:any, /.*schoolloop\.com\/.*/)
         | 
| 32 | 
            +
                      .to_return(status: 401, body: "ERROR: Authorization failed: password incorrect.")
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                  it "raises an exception" do
         | 
| 35 | 
            +
                    expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::Unauthorized)
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                context "400 Bad Request" do
         | 
| 40 | 
            +
                  before(:each) do
         | 
| 41 | 
            +
                    stub_request(:any, /.*schoolloop\.com\/.*/)
         | 
| 42 | 
            +
                      .to_return(status: 400, body: "some error message")
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  it "raises an exception" do
         | 
| 46 | 
            +
                    expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::BadRequest, "some error message")
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                context "404" do
         | 
| 51 | 
            +
                  before(:each) do
         | 
| 52 | 
            +
                    stub_request(:any, /.*schoolloop\.com\/.*/)
         | 
| 53 | 
            +
                      .to_return(status: 404, body: "not found")
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  it "raises an exception" do
         | 
| 57 | 
            +
                    expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::ServiceError, "not found")
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                context "503" do
         | 
| 62 | 
            +
                  before(:each) do
         | 
| 63 | 
            +
                    stub_request(:any, /.*schoolloop\.com\/.*/)
         | 
| 64 | 
            +
                      .to_return(status: 503, body: "backend failure")
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  it "raises an exception" do
         | 
| 68 | 
            +
                    expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::ServiceError, "backend failure")
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                context "timeout" do
         | 
| 73 | 
            +
                  before(:each) do
         | 
| 74 | 
            +
                    stub_request(:any, /.*schoolloop\.com\/.*/).to_timeout
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  it "raises an exception" do
         | 
| 78 | 
            +
                    expect { unauth_client.get_roster }.to raise_error(Faraday::TimeoutError)
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
             | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
            end
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SchoolLoop::Configuration do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              describe ".configure" do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                it "sets global configuration settings" do
         | 
| 8 | 
            +
                  SchoolLoop.configure do |config|
         | 
| 9 | 
            +
                    config.username = "test2"
         | 
| 10 | 
            +
                    config.password = "setting2"
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  expect(SchoolLoop.options[:username]).to eq "test2"
         | 
| 14 | 
            +
                  expect(SchoolLoop.options[:password]).to eq "setting2"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  client = SchoolLoop.new
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  expect(client.username).to eq "test2"
         | 
| 19 | 
            +
                  expect(client.password).to eq "setting2"
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                it "allows the user to specify extra config options" do
         | 
| 23 | 
            +
                  SchoolLoop.configure do |config|
         | 
| 24 | 
            +
                    config.connection_options = {ssl: {verify: false}, request: {timeout: 1234}}
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  client = SchoolLoop.new
         | 
| 28 | 
            +
                  expect(client.connection.options.timeout).to eq 1234
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                describe ":secure" do
         | 
| 32 | 
            +
                  it { expect(SchoolLoop.new(secure: false, subdomain: "test").connection.url_prefix.scheme).to eq "http" }
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  it { expect(SchoolLoop.new(secure: true, subdomain: "test").connection.url_prefix.scheme).to eq "https" }
         | 
| 35 | 
            +
                  it { expect(SchoolLoop.new(subdomain: "test").connection.url_prefix.scheme).to eq "https" }
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
             | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SchoolLoop::Resources::ProgressReports do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let(:client) do
         | 
| 6 | 
            +
                SchoolLoop.new do |config|
         | 
| 7 | 
            +
                  config.subdomain  = 'subdomain'
         | 
| 8 | 
            +
                  config.username   = 'username'
         | 
| 9 | 
            +
                  config.password   = 'password'
         | 
| 10 | 
            +
                  config.adapter    = :net_http
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              describe "#publish_progress_report" do
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                it "publishes a progress report" do
         | 
| 17 | 
            +
                  stub_request(:post, "https://username:password@subdomain.schoolloop.com/api/progressReports")
         | 
| 18 | 
            +
                    .to_return(status: 200, body: "SUCCESS\n")
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  response = client.publish_progress_report("<xml/>")
         | 
| 21 | 
            +
                  expect(a_request(:post, /.*subdomain\.schoolloop\.com\/api\/progressReports/)).to have_been_made.once
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  expect(response.status).to eq 200
         | 
| 24 | 
            +
                  expect(response.body).to eq "SUCCESS\n"
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                context "errors" do
         | 
| 28 | 
            +
                  before(:each) do
         | 
| 29 | 
            +
                    stub_request(:any, /.*schoolloop\.com\/.*/)
         | 
| 30 | 
            +
                      .to_return(status: 400, body: "Error: failed to parse XML reports. No reports found. Check XML syntax.")
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 34 | 
            +
                  it { expect { client.publish_progress_report("<xml/>") }.to raise_error(SchoolLoop::Error::BadRequest) }
         | 
| 35 | 
            +
                  it { expect { client.publish_progress_report("<xml/>") }.to raise_error("Error: failed to parse XML reports. No reports found. Check XML syntax.") }
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SchoolLoop::Resources::Roster do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let(:client) do
         | 
| 6 | 
            +
                SchoolLoop.new do |config|
         | 
| 7 | 
            +
                  config.subdomain  = 'subdomain'
         | 
| 8 | 
            +
                  config.username   = 'username'
         | 
| 9 | 
            +
                  config.password   = 'password'
         | 
| 10 | 
            +
                  config.adapter    = :net_http
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              describe "#get_roster" do
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                before do
         | 
| 17 | 
            +
                  stub_request(:get, /.*schoolloop\.com\/api\/roster.*/)
         | 
| 18 | 
            +
                    .to_return(status: 200, body: fixture("roster_response.xml").read,
         | 
| 19 | 
            +
                      headers: {'Content-Type' => 'text/xml'}
         | 
| 20 | 
            +
                    )
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                it "for entire school" do
         | 
| 24 | 
            +
                  response = client.get_roster
         | 
| 25 | 
            +
                  expect(a_request(:get, /.*subdomain\.schoolloop\.com\/api\/roster/)).to have_been_made.once
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  expect(response.status).to eq 200
         | 
| 28 | 
            +
                  expect(response.body).to be_a Nokogiri::XML::Document
         | 
| 29 | 
            +
                  expect(response.body.xpath("//root/roster/teachers/teacher")[0].attr("name")).to eq "Reynolds, Mr. Malcom"
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                it "for a specific teacher" do
         | 
| 33 | 
            +
                  response = client.get_roster("12345")
         | 
| 34 | 
            +
                  expect(a_request(:get, /.*subdomain\.schoolloop\.com\/api\/roster/).with(query: {teacher_id: "12345"})).to have_been_made.once
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  expect(response.status).to eq 200
         | 
| 37 | 
            +
                  expect(response.body).to be_a Nokogiri::XML::Document
         | 
| 38 | 
            +
                  expect(response.body.xpath("//root/roster/teachers/teacher")[0].attr("name")).to eq "Reynolds, Mr. Malcom"
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SchoolLoop do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              describe ".new" do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                it "allows an instance to override the global configuration" do
         | 
| 8 | 
            +
                  SchoolLoop.configure do |config|
         | 
| 9 | 
            +
                    config.username = "test2"
         | 
| 10 | 
            +
                    config.password = "setting2"
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  client = SchoolLoop.new
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  expect(client.username).to eq "test2"
         | 
| 16 | 
            +
                  expect(client.password).to eq "setting2"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  client2 = SchoolLoop.new(username: "test3", password: "setting3")
         | 
| 19 | 
            +
                  expect(client2.username).to eq "test3"
         | 
| 20 | 
            +
                  expect(client2.password).to eq "setting3"
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  expect(client.username).to eq "test2"
         | 
| 23 | 
            +
                  expect(client.password).to eq "setting2"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  client3 = SchoolLoop.new(username: "test4")
         | 
| 26 | 
            +
                  expect(client3.username).to eq "test4"
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                it "does not modify the global configuration" do
         | 
| 30 | 
            +
                  SchoolLoop.configure do |config|
         | 
| 31 | 
            +
                    config.username = "testg"
         | 
| 32 | 
            +
                    config.password = "passg"
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  client = SchoolLoop.new(username: "gtest", password: "gpass")
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  expect(client.username).to eq "gtest"
         | 
| 38 | 
            +
                  expect(client.password).to eq "gpass"
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  expect(SchoolLoop.options[:username]).to eq "testg"
         | 
| 41 | 
            +
                  expect(SchoolLoop.options[:password]).to eq "passg"
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 46 | 
            +
              describe ".method_missing" do
         | 
| 47 | 
            +
                let(:client_dbl) { double(SchoolLoop::Client) }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                before do
         | 
| 50 | 
            +
                  allow(SchoolLoop).to receive(:new).and_return(client_dbl)
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                it "creates an instance and calls the method" do
         | 
| 54 | 
            +
                  expect(client_dbl).to receive(:get_roster).with("1234").and_return(true)
         | 
| 55 | 
            +
                  expect(SchoolLoop.get_roster("1234")).to be_truthy
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              describe ".respond_to?" do
         | 
| 60 | 
            +
                it { expect(SchoolLoop).to respond_to(:get_roster) }
         | 
| 61 | 
            +
                it { expect(SchoolLoop).to respond_to(:publish_progress_report) }
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,143 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: school_loop
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Mitch Dempsey
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2015-09-03 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bundler
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '1.0'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '1.0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: faraday
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0.9'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0.9'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: faraday_middleware
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0.9'
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0.9'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: nokogiri
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - ">="
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: 1.5.2
         | 
| 62 | 
            +
              type: :runtime
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - ">="
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: 1.5.2
         | 
| 69 | 
            +
            description: Client for School Loop API (OpenLoop)
         | 
| 70 | 
            +
            email:
         | 
| 71 | 
            +
            - mitch@mitchdempsey.com
         | 
| 72 | 
            +
            executables: []
         | 
| 73 | 
            +
            extensions: []
         | 
| 74 | 
            +
            extra_rdoc_files: []
         | 
| 75 | 
            +
            files:
         | 
| 76 | 
            +
            - ".gitignore"
         | 
| 77 | 
            +
            - ".rspec"
         | 
| 78 | 
            +
            - ".ruby-version"
         | 
| 79 | 
            +
            - ".travis.yml"
         | 
| 80 | 
            +
            - Gemfile
         | 
| 81 | 
            +
            - Gemfile.lock
         | 
| 82 | 
            +
            - LICENSE
         | 
| 83 | 
            +
            - README.md
         | 
| 84 | 
            +
            - Rakefile
         | 
| 85 | 
            +
            - lib/school_loop.rb
         | 
| 86 | 
            +
            - lib/school_loop/client.rb
         | 
| 87 | 
            +
            - lib/school_loop/configuration.rb
         | 
| 88 | 
            +
            - lib/school_loop/connection.rb
         | 
| 89 | 
            +
            - lib/school_loop/error.rb
         | 
| 90 | 
            +
            - lib/school_loop/error/bad_request.rb
         | 
| 91 | 
            +
            - lib/school_loop/error/service_error.rb
         | 
| 92 | 
            +
            - lib/school_loop/error/unauthorized.rb
         | 
| 93 | 
            +
            - lib/school_loop/resources.rb
         | 
| 94 | 
            +
            - lib/school_loop/resources/progress_reports.rb
         | 
| 95 | 
            +
            - lib/school_loop/resources/roster.rb
         | 
| 96 | 
            +
            - lib/school_loop/response.rb
         | 
| 97 | 
            +
            - lib/school_loop/response/raise_error.rb
         | 
| 98 | 
            +
            - lib/school_loop/response/xmlize.rb
         | 
| 99 | 
            +
            - lib/school_loop/version.rb
         | 
| 100 | 
            +
            - school_loop.gemspec
         | 
| 101 | 
            +
            - spec/fixtures/progress_report_submission.xml
         | 
| 102 | 
            +
            - spec/fixtures/roster_response.xml
         | 
| 103 | 
            +
            - spec/helper.rb
         | 
| 104 | 
            +
            - spec/school_loop/client_spec.rb
         | 
| 105 | 
            +
            - spec/school_loop/configuration_spec.rb
         | 
| 106 | 
            +
            - spec/school_loop/resources/progress_reports_spec.rb
         | 
| 107 | 
            +
            - spec/school_loop/resources/roster_spec.rb
         | 
| 108 | 
            +
            - spec/school_loop/response/xmlize_spec.rb
         | 
| 109 | 
            +
            - spec/school_loop_spec.rb
         | 
| 110 | 
            +
            homepage: https://github.com/webdestroya/school_loop
         | 
| 111 | 
            +
            licenses:
         | 
| 112 | 
            +
            - MIT
         | 
| 113 | 
            +
            metadata: {}
         | 
| 114 | 
            +
            post_install_message: 
         | 
| 115 | 
            +
            rdoc_options: []
         | 
| 116 | 
            +
            require_paths:
         | 
| 117 | 
            +
            - lib
         | 
| 118 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 119 | 
            +
              requirements:
         | 
| 120 | 
            +
              - - ">="
         | 
| 121 | 
            +
                - !ruby/object:Gem::Version
         | 
| 122 | 
            +
                  version: '0'
         | 
| 123 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 124 | 
            +
              requirements:
         | 
| 125 | 
            +
              - - ">="
         | 
| 126 | 
            +
                - !ruby/object:Gem::Version
         | 
| 127 | 
            +
                  version: '0'
         | 
| 128 | 
            +
            requirements: []
         | 
| 129 | 
            +
            rubyforge_project: 
         | 
| 130 | 
            +
            rubygems_version: 2.4.5
         | 
| 131 | 
            +
            signing_key: 
         | 
| 132 | 
            +
            specification_version: 4
         | 
| 133 | 
            +
            summary: Client for School Loop API (OpenLoop)
         | 
| 134 | 
            +
            test_files:
         | 
| 135 | 
            +
            - spec/fixtures/progress_report_submission.xml
         | 
| 136 | 
            +
            - spec/fixtures/roster_response.xml
         | 
| 137 | 
            +
            - spec/helper.rb
         | 
| 138 | 
            +
            - spec/school_loop/client_spec.rb
         | 
| 139 | 
            +
            - spec/school_loop/configuration_spec.rb
         | 
| 140 | 
            +
            - spec/school_loop/resources/progress_reports_spec.rb
         | 
| 141 | 
            +
            - spec/school_loop/resources/roster_spec.rb
         | 
| 142 | 
            +
            - spec/school_loop/response/xmlize_spec.rb
         | 
| 143 | 
            +
            - spec/school_loop_spec.rb
         |