spec: add base provider states for contract tests
refs QUIZ-4638 With a "base" provider state we can easily manage any number of provider states from which all other provider states will inherit. Change-Id: Ic92dcb4b4649d334abdc64c622f252b5ec5825b6 Reviewed-on: https://gerrit.instructure.com/155564 Tested-by: Jenkins Reviewed-by: Gentry Beckmann <gbeckmann@instructure.com> Product-Review: Michael Hargiss <mhargiss@instructure.com> QA-Review: Michael Hargiss <mhargiss@instructure.com>
This commit is contained in:
parent
f93a0149ed
commit
9e3de1c6ec
|
@ -22,26 +22,27 @@ require_relative '../pact_config'
|
|||
require_relative '../../../spec_helper'
|
||||
require_relative 'pact_setup'
|
||||
require_relative 'proxy_app'
|
||||
Dir[File.dirname(__FILE__) + "/provider_states_for_consumer/*.rb"].each {|f| require f }
|
||||
require_relative 'provider_states_for_consumer'
|
||||
|
||||
Pact.service_provider PactConfig::Providers::CANVAS_LMS_API do
|
||||
app { PactApiConsumerProxy.new }
|
||||
|
||||
pact_path = format(
|
||||
'pacts/provider/%<provider>s/consumer/%<consumer>s',
|
||||
provider: ERB::Util.url_encode(PactConfig::Providers::CANVAS_LMS_API),
|
||||
consumer: ERB::Util.url_encode(PactConfig::Consumers::GENERIC_CONSUMER)
|
||||
)
|
||||
PactConfig::Consumers::ALL.each do |consumer|
|
||||
pact_path = format(
|
||||
'pacts/provider/%<provider>s/consumer/%<consumer>s',
|
||||
provider: ERB::Util.url_encode(PactConfig::Providers::CANVAS_LMS_API),
|
||||
consumer: ERB::Util.url_encode(consumer)
|
||||
)
|
||||
|
||||
honours_pact_with PactConfig::Consumers::GENERIC_CONSUMER do
|
||||
|
||||
if PactConfig.jenkins_build? then
|
||||
honours_pact_with consumer do
|
||||
pact_uri PactConfig.pact_uri(pact_path: pact_path)
|
||||
else
|
||||
pact_uri 'pacts/generic_consumer-canvas_lms_api.json'
|
||||
end
|
||||
|
||||
app_version PactConfig::Providers::CANVAS_API_VERSION
|
||||
publish_verification_results true
|
||||
if !PactConfig.jenkins_build? && consumer == 'Generic Consumer'
|
||||
pact_uri 'pacts/generic_consumer-canvas_lms_api.json'
|
||||
end
|
||||
|
||||
app_version PactConfig::Providers::CANVAS_API_VERSION
|
||||
publish_verification_results true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Dir[File.dirname(__FILE__) + "/provider_states_for_consumer/*.rb"].each {|f| require f }
|
||||
require 'spec/factories/course_factory'
|
||||
require 'spec/factories/user_factory'
|
||||
|
||||
PactConfig::Consumers::ALL.each do |consumer|
|
||||
Pact.provider_states_for consumer do
|
||||
set_up do
|
||||
Pact::Canvas.base_state = Pact::Canvas::BaseState.seed!
|
||||
end
|
||||
|
||||
# The following states are provided by the set_up block above, thus the no_op
|
||||
# because no additional setup is required.
|
||||
provider_state('an account') { no_op }
|
||||
provider_state('a course') { no_op }
|
||||
provider_state('a student enrolled in a course') { no_op }
|
||||
provider_state('a teacher enrolled in a course') { no_op }
|
||||
provider_state('a teacher assistant enrolled in a course') { no_op }
|
||||
provider_state('an observer enrolled in a course') { no_op }
|
||||
provider_state('an account admin') { no_op }
|
||||
provider_state('a site admin') { no_op }
|
||||
end
|
||||
end
|
||||
|
||||
module Pact::Canvas
|
||||
def self.base_state=(base_state)
|
||||
@base_state ||= base_state
|
||||
end
|
||||
|
||||
def self.base_state
|
||||
@base_state
|
||||
end
|
||||
|
||||
class BaseState
|
||||
include Factories
|
||||
|
||||
attr_reader(
|
||||
:account,
|
||||
:account_admins,
|
||||
:course,
|
||||
:observers,
|
||||
:site_admins,
|
||||
:site_admin_account,
|
||||
:students,
|
||||
:teachers,
|
||||
:teacher_assistants
|
||||
)
|
||||
|
||||
def self.seed!(opts: {})
|
||||
self.new(opts)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(opts)
|
||||
@site_admin_account = opts[:site_admin_account] || Account.site_admin
|
||||
@account = opts[:account] || Account.default
|
||||
@course = opts[:course] || seed_course
|
||||
seed_users(opts)
|
||||
end
|
||||
|
||||
def seed_course
|
||||
course_factory(account: @account, active_course: true, course_name: 'Contract Tests Course')
|
||||
end
|
||||
|
||||
def seed_users(opts)
|
||||
@site_admins = opts[:site_admins] || seed_site_admins
|
||||
@account_admins = opts[:account_admins] || seed_account_admins
|
||||
@teachers = opts[:teachers] || seed_teachers
|
||||
@teacher_assistants = opts[:teacher_assistants] || seed_teacher_assistants
|
||||
@students = opts[:students] || seed_students
|
||||
@observers = opts[:observers] || seed_observers
|
||||
end
|
||||
|
||||
def seed_site_admins(count: 1)
|
||||
site_admins = []
|
||||
count.times do |i|
|
||||
index = i + 1
|
||||
site_admin_name = "SiteAdmin#{index}"
|
||||
site_admin_email = "#{site_admin_name}@instructure.com"
|
||||
site_admin = account_admin_user(account: @site_admin_account, email: site_admin_email, name: site_admin_name)
|
||||
site_admin.pseudonyms.create!(unique_id: site_admin_email, password: 'password', password_confirmation: 'password')
|
||||
site_admin.email = site_admin_email
|
||||
site_admin.accept_terms
|
||||
site_admins << site_admin
|
||||
end
|
||||
site_admins
|
||||
end
|
||||
|
||||
def seed_account_admins(count: 1)
|
||||
account_admins = []
|
||||
count.times do |i|
|
||||
index = i + 1
|
||||
admin_name = "Admin#{index}"
|
||||
admin_email = "#{admin_name}@instructure.com"
|
||||
admin = account_admin_user(account: @account, email: admin_email, name: admin_name)
|
||||
admin.pseudonyms.create!(unique_id: admin_email, password: 'password', password_confirmation: 'password')
|
||||
admin.email = admin_email
|
||||
admin.accept_terms
|
||||
account_admins << admin
|
||||
end
|
||||
account_admins
|
||||
end
|
||||
|
||||
def seed_teachers(count: 1)
|
||||
teachers = []
|
||||
count.times do |i|
|
||||
index = i + 1
|
||||
teacher_name = "Teacher#{index}"
|
||||
teacher_email = "#{teacher_name}@instructure.com"
|
||||
teacher = user_factory(active_all: true, course: @course, name: teacher_name)
|
||||
teacher.pseudonyms.create!(unique_id: teacher_email, password: 'password', password_confirmation: 'password')
|
||||
teacher.email = teacher_email
|
||||
teacher.accept_terms
|
||||
course.enroll_teacher(teacher).accept!
|
||||
teachers << teacher
|
||||
end
|
||||
teachers
|
||||
end
|
||||
|
||||
def seed_teacher_assistants(count: 1)
|
||||
teacher_assistants = []
|
||||
count.times do |i|
|
||||
index = i + 1
|
||||
ta_name = "TeacherAssistant#{index}"
|
||||
ta_email = "#{ta_name}@instructure.com"
|
||||
ta = user_factory(active_all: true, course: @course, name: ta_name)
|
||||
ta.pseudonyms.create!(unique_id: ta_email, password: 'password', password_confirmation: 'password')
|
||||
ta.email = ta_email
|
||||
ta.accept_terms
|
||||
course.enroll_ta(ta).accept!
|
||||
teacher_assistants << ta
|
||||
end
|
||||
teacher_assistants
|
||||
end
|
||||
|
||||
def seed_students(count: 1)
|
||||
students = []
|
||||
count.times do |i|
|
||||
index = i + 1
|
||||
student_name = "Student#{index}"
|
||||
student_email = "#{student_name}@instructure.com"
|
||||
student = user_factory(active_all: true, course: @course, name: student_name)
|
||||
student.pseudonyms.create!(unique_id: student_email, password: 'password', password_confirmation: 'password')
|
||||
student.email = student_email
|
||||
student.accept_terms
|
||||
course.enroll_student(student).accept!
|
||||
students << student
|
||||
end
|
||||
students
|
||||
end
|
||||
|
||||
def seed_observers(count: 1)
|
||||
observers = []
|
||||
count.times do |i|
|
||||
index = i + 1
|
||||
observer_name = "Observer#{index}"
|
||||
observer_email = "#{observer_name}@instructure.com"
|
||||
observer = user_factory(active_all: true, course: @course, name: observer_name)
|
||||
observer.pseudonyms.create!(unique_id: observer_email, password: 'password', password_confirmation: 'password')
|
||||
observer.email = observer_email
|
||||
observer.accept_terms
|
||||
enroll_observer(observer: observer)
|
||||
observers << observer
|
||||
end
|
||||
observers
|
||||
end
|
||||
|
||||
def enroll_observer(observer:, student_to_observe: nil)
|
||||
student = student_to_observe || @students.first
|
||||
@course.enroll_user(
|
||||
observer,
|
||||
'ObserverEnrollment',
|
||||
enrollment_state: 'active',
|
||||
associated_user_id: student.id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
PactConfig::Consumers::ALL.each do |consumer|
|
||||
Pact.provider_states_for consumer do
|
||||
provider_state 'a quiz' do
|
||||
set_up do
|
||||
course = Pact::Canvas.base_state.course
|
||||
quiz_model(course: course)
|
||||
end
|
||||
end
|
||||
|
||||
provider_state 'a migrated quiz' do
|
||||
set_up do
|
||||
course = Pact::Canvas.base_state.course
|
||||
quiz = quiz_model(course: course)
|
||||
quiz.migration_id = 'i09d7615b43e5f35589cc1e2647dd345f'
|
||||
quiz.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,18 +21,20 @@ class PactApiConsumerProxy
|
|||
USER_HEADER = 'HTTP_AUTH_USER'.freeze
|
||||
|
||||
def call(env)
|
||||
# Users calling the API will know the user ID of the
|
||||
# user that they want to identify as. These are given
|
||||
# in the provider state descriptions.
|
||||
# Users calling the API will know the user name of the
|
||||
# user that they want to identify as. For example, "Admin1".
|
||||
if expects_auth_header?(env)
|
||||
user = find_requesting_user(env)
|
||||
|
||||
# You can create an access token without having a pseudonym;
|
||||
# however, when Canvas receives a request and looks up the user
|
||||
# for that access token, it expects that user to have a pseudonym.
|
||||
Pseudonym.create!(user: user, unique_id: "#{user.name}@instructure.com")
|
||||
Pseudonym.create!(user: user, unique_id: "#{user.name}@instructure.com") if user.pseudonyms.empty?
|
||||
token = user.access_tokens.create!.full_token
|
||||
|
||||
env[AUTH_HEADER] = "Bearer #{token}"
|
||||
end
|
||||
|
||||
# Unset the 'AUTH_USER' header -- that's only for this proxy,
|
||||
# don't pass it along to Canvas.
|
||||
env.delete(USER_HEADER)
|
||||
|
@ -47,12 +49,12 @@ class PactApiConsumerProxy
|
|||
end
|
||||
|
||||
def find_requesting_user(env)
|
||||
user = User.first
|
||||
|
||||
user_name = env[USER_HEADER]
|
||||
if user_name
|
||||
user = User.where(name: user_name).first
|
||||
raise "There is no user with name #{user_name}." unless user
|
||||
else
|
||||
user = User.first
|
||||
end
|
||||
|
||||
user
|
||||
|
|
Loading…
Reference in New Issue