# QuizApiClient Welcome! ## Installation Add this line to your application's Gemfile: ```ruby gem 'quiz_api_client' ``` And then execute: $ bundle Or install it yourself as: $ gem install quiz_api_client ## Usage This client library is used to access quiz_api through Signed Auth, our implementation of signing a JWT with the appropriate scope and resource_id. Currently, the "services" are organized by resource, following the REST convention of pluralization. ### Instantiate the Client To instantiate a client, you'll need the secret and the host. ```ruby client = QuizApiClient::Client.new( consumer_key: 'the consumer key normally stored in the quiz_api signed_auth_consumers table', host: 'your-quiz-api-host-here.com', shared_secret: 'the-api-secret normally stored on the quiz_api account', protocol: 'http' # Set this to what you need, ideally it's an environment variable ) ``` ### Creation of Tokens JWTs are created without hitting quiz_api and and they are validated on quiz_api. Tokens are created for a given scope, expiration, and an optional resource_id. Example, generate a token for building: ```ruby client.jwt_service.grant_permission( scope: 'quiz.build', exp: Time.now.utc.to_i + 60, # some reasonable time, obviously longer is more a security risk resource_id: 1) ``` ### Calling the API Example, create a Quiz: ```ruby client.quizzes_service.create( params: { title: 'My quiz' }, token: my_scoped_token ) ``` ### Currently Supported Functionality #### Quizzes Service ```ruby # Create Quiz client.quizzes_service.create(token:, params:) # List Quizzes client.quizzes_service.list(token:, params:) ``` #### Quiz Entries Service ```ruby # Get Quiz Entries client.quiz_entries_service.list( token: my_scoped_token, params: { id: quiz_id } ) ``` #### Quiz Session Service ```ruby # Update Quiz Session client.quiz_session_service.update( token: my_scoped_token, params: { id: quiz_session_id, # Other params here } ) ``` #### Quiz Sessions Service ```ruby # Create Quiz Session client.quiz_sessions_service.create( token: my_scoped_token, params: { quiz_id: quiz_id_to_create_session_under } ) ``` #### QTI Imports Service ```ruby # Create QTI Import client.qti_imports_service.create( token: my_scoped_token, params: { quiz_id: quiz_id_to_create_import_under, qti_import: { url: url where QTI Export is stored } } ) ``` #### Item Analyses Service ```ruby # List item analyses client.item_analyses_service.list( token: my_scoped_token, params: { quiz_id: quiz_id_to_list_items_under } ) # get specific item analysis client.item_analyses_service.get( token: my_scoped_token, params: { quiz_id: quiz_id_to_list_items_under, id: item_id_to_get_under } ) ``` #### Quiz Analyses Service ```ruby # get specific item analysis client.quiz_analyses_service.get( token: my_scoped_token, params: { quiz_id: quiz_id_to_get_analysis } ) ``` #### Quiz Session Events Service ```ruby # list quiz session events client.quiz_session_events_service.list( token: my_scoped_token, params: { quiz_session_id: quiz_session_id_to_get_events_under } ) ``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bundle exec rake console` for an interactive prompt that will allow you to experiment. To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). When you add or modify a service, be sure to add or modify contract tests! ## Contract Tests We use [Pact](https://docs.pact.io/) for our contract testing. To generate a Pact file, run `bin/contracts`. The `bin/contracts` script will generate the Pact file and place it in the pacts/ directory. It will also attempt to publish the Pact file to a local Pact Broker. ### Development Workflow: 1. In the quiz_api repo, spin up the Quiz API service with `bin/dev-setup` 2. In the quiz_pact_broker repo, spin up a Pact Broker with `bin/dev-setup` 3. In the quiz_api repo, write Pact provider states in the spec/service_consumers/quiz_api_client_ruby/ directory as needed 4. In this repo's spec/contracts/ directory, write or modify a contract test 5. In this repo, run `bin/contracts` to generate a Pact file and publish it to the Pact Broker 6. In the quiz_api repo, run `bin/contracts` to pull the new Pact file from the Pact Broker and run the updated contract tests against the Quiz API service Bonus: You can view your Pact file in the Pact Broker at http://pact-broker.docker along with some cool goodies! ### Debugging Failures Pact has some basic RSpec output for failed specs. It also keeps a log in `log/pact.log` and offers general pointers for debugging. Above all, learn the Pact [basics](https://docs.pact.io/documentation/matching.html). ### What should contract tests cover? The aim of contract testing here is *not* to test all functional requirements of the Quiz API service. Rather, the goal is to ensure changes to the Quiz API service don't break its clients. We can best accomplish this with the following contract test coverage: - Basic happy path requests for all endpoints (POST, GET, PUT, DELETE) - Basic error paths for all endpoints (verify the error messages and/or HTTP response codes are accurate) - Resource state management; for example, when a quiz attempt is submitted but not yet graded - Special edge case errors Again, what *not* to test: the functional behavior of the service; for example, a series of sequential API calls to test a full user scenario.