coalescing_panda 3.2.3 → 4.0.0
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 +4 -4
 - data/app/models/coalescing_panda/assignment.rb +1 -1
 - data/app/models/coalescing_panda/course.rb +7 -7
 - data/app/models/coalescing_panda/group.rb +1 -1
 - data/app/models/coalescing_panda/section.rb +1 -1
 - data/app/models/coalescing_panda/user.rb +2 -2
 - data/app/models/coalescing_panda/workers/course_miner.rb +112 -68
 - data/lib/coalescing_panda/version.rb +1 -1
 - data/spec/controllers/coalescing_panda/lti_controller_spec.rb +2 -7
 - data/spec/controllers/coalescing_panda/oauth2_controller_spec.rb +5 -3
 - data/spec/dummy/db/schema.rb +30 -49
 - data/spec/dummy/db/test.sqlite3 +0 -0
 - data/spec/dummy/log/test.log +33040 -0
 - data/spec/models/coalescing_panda/workers/course_miner_spec.rb +13 -77
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 2e03abaf5ab4b91ee3a3da95d3773053a81beb92
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b90dd5bd727507dec0c380bd73f141f6f29fef8a
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 4e54f1e4062e06bbcdf5e1027e50354ac5fcc9f9f170957a3ce49a5f7fc1a8634af05667bf9cfb6c404b2fa562fd575b2e54814e2ae5051654922b0eaa213b0c
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: a0bab028c1b5db95f3b7cf5a97474acf635b79aee71cc8e43714f11b1f37a77d3ee753a6c73cce946341089c560563d88be6ead658230a65dfb08b8d70f9fe5c
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module CoalescingPanda
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Assignment < ActiveRecord::Base
         
     | 
| 
       3 
3 
     | 
    
         
             
                belongs_to :course, foreign_key: :coalescing_panda_course_id, class_name: 'CoalescingPanda::Course'
         
     | 
| 
       4 
     | 
    
         
            -
                has_many :submissions, foreign_key: :coalescing_panda_assignment_id, class_name: 'CoalescingPanda::Submission'
         
     | 
| 
      
 4 
     | 
    
         
            +
                has_many :submissions, foreign_key: :coalescing_panda_assignment_id, class_name: 'CoalescingPanda::Submission', dependent: :destroy
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                delegate :account, to: :course
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
         @@ -2,14 +2,14 @@ module CoalescingPanda 
     | 
|
| 
       2 
2 
     | 
    
         
             
              class Course < ActiveRecord::Base
         
     | 
| 
       3 
3 
     | 
    
         
             
                belongs_to :account, foreign_key: :coalescing_panda_lti_account_id, class_name: 'CoalescingPanda::LtiAccount'
         
     | 
| 
       4 
4 
     | 
    
         
             
                belongs_to :term, foreign_key: :coalescing_panda_term_id, class_name: 'CoalescingPanda::Term'
         
     | 
| 
       5 
     | 
    
         
            -
                has_many :sections, foreign_key: :coalescing_panda_course_id, class_name: 'CoalescingPanda::Section'
         
     | 
| 
       6 
     | 
    
         
            -
                has_many :enrollments, through: :sections
         
     | 
| 
       7 
     | 
    
         
            -
                has_many :assignments, foreign_key: :coalescing_panda_course_id, class_name: 'CoalescingPanda::Assignment'
         
     | 
| 
       8 
     | 
    
         
            -
                has_many :submissions, through: :assignments
         
     | 
| 
      
 5 
     | 
    
         
            +
                has_many :sections, foreign_key: :coalescing_panda_course_id, class_name: 'CoalescingPanda::Section', dependent: :destroy
         
     | 
| 
      
 6 
     | 
    
         
            +
                has_many :enrollments, through: :sections, dependent: :destroy
         
     | 
| 
      
 7 
     | 
    
         
            +
                has_many :assignments, foreign_key: :coalescing_panda_course_id, class_name: 'CoalescingPanda::Assignment', dependent: :destroy
         
     | 
| 
      
 8 
     | 
    
         
            +
                has_many :submissions, through: :assignments, dependent: :destroy
         
     | 
| 
       9 
9 
     | 
    
         
             
                has_many :users, through: :sections, source: :users, class_name: 'CoalescingPanda::User'
         
     | 
| 
       10 
     | 
    
         
            -
                has_many :groups, :as => :context, class_name: 'CoalescingPanda::Group'
         
     | 
| 
       11 
     | 
    
         
            -
                has_many :group_memberships, through: :groups, source: :group_memberships, class_name: 'CoalescingPanda::GroupMembership'
         
     | 
| 
       12 
     | 
    
         
            -
                has_many :canvas_batches, as: :context
         
     | 
| 
      
 10 
     | 
    
         
            +
                has_many :groups, :as => :context, class_name: 'CoalescingPanda::Group', dependent: :destroy
         
     | 
| 
      
 11 
     | 
    
         
            +
                has_many :group_memberships, through: :groups, source: :group_memberships, class_name: 'CoalescingPanda::GroupMembership', dependent: :destroy
         
     | 
| 
      
 12 
     | 
    
         
            +
                has_many :canvas_batches, as: :context, dependent: :destroy
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                validates :coalescing_panda_lti_account_id, presence: true
         
     | 
| 
       15 
15 
     | 
    
         
             
                validates :canvas_course_id, presence: true
         
     | 
| 
         @@ -3,7 +3,7 @@ module CoalescingPanda 
     | 
|
| 
       3 
3 
     | 
    
         
             
                belongs_to :context, :polymorphic => true
         
     | 
| 
       4 
4 
     | 
    
         
             
                include SingleTablePolymorphic
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
                has_many :group_memberships, dependent: :destroy, foreign_key: :coalescing_panda_group_id, class_name: 'CoalescingPanda::GroupMembership'
         
     | 
| 
      
 6 
     | 
    
         
            +
                has_many :group_memberships, dependent: :destroy, foreign_key: :coalescing_panda_group_id, class_name: 'CoalescingPanda::GroupMembership', dependent: :destroy
         
     | 
| 
       7 
7 
     | 
    
         
             
                validates :group_category_id, presence: true
         
     | 
| 
       8 
8 
     | 
    
         
             
                validates :canvas_group_id, presence: true
         
     | 
| 
       9 
9 
     | 
    
         
             
                validates :coalescing_panda_user_id, presence: true
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module CoalescingPanda
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Section < ActiveRecord::Base
         
     | 
| 
       3 
3 
     | 
    
         
             
                belongs_to :course, foreign_key: :coalescing_panda_course_id, class_name: 'CoalescingPanda::Course'
         
     | 
| 
       4 
     | 
    
         
            -
                has_many :enrollments, foreign_key: :coalescing_panda_section_id, class_name: 'CoalescingPanda::Enrollment'
         
     | 
| 
      
 4 
     | 
    
         
            +
                has_many :enrollments, foreign_key: :coalescing_panda_section_id, class_name: 'CoalescingPanda::Enrollment', dependent: :destroy
         
     | 
| 
       5 
5 
     | 
    
         
             
                has_many :users, through: :enrollments, class_name: 'CoalescingPanda::User'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                delegate :account, to: :course
         
     | 
| 
         @@ -1,8 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module CoalescingPanda
         
     | 
| 
       2 
2 
     | 
    
         
             
              class User < ActiveRecord::Base
         
     | 
| 
       3 
3 
     | 
    
         
             
                belongs_to :account, foreign_key: :coalescing_panda_lti_account_id, class_name: 'CoalescingPanda::LtiAccount'
         
     | 
| 
       4 
     | 
    
         
            -
                has_many :enrollments, foreign_key: :coalescing_panda_user_id, class_name: 'CoalescingPanda::Enrollment'
         
     | 
| 
       5 
     | 
    
         
            -
                has_many :submissions, foreign_key: :coalescing_panda_user_id, class_name: 'CoalescingPanda::Submission'
         
     | 
| 
      
 4 
     | 
    
         
            +
                has_many :enrollments, foreign_key: :coalescing_panda_user_id, class_name: 'CoalescingPanda::Enrollment', dependent: :destroy
         
     | 
| 
      
 5 
     | 
    
         
            +
                has_many :submissions, foreign_key: :coalescing_panda_user_id, class_name: 'CoalescingPanda::Submission', dependent: :destroy
         
     | 
| 
       6 
6 
     | 
    
         
             
                has_many :sections, through: :enrollments
         
     | 
| 
       7 
7 
     | 
    
         
             
                has_many :courses, through: :sections
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
         @@ -1,13 +1,17 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class CoalescingPanda::Workers::CourseMiner
         
     | 
| 
       2 
2 
     | 
    
         
             
              SUPPORTED_MODELS = [:sections, :users, :enrollments, :assignments, :submissions, :groups, :group_memberships] #ORDER MATTERS!!
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
              attr_accessor :options, :account, :course, :batch
         
     | 
| 
      
 4 
     | 
    
         
            +
              attr_accessor :options, :account, :course, :batch, :course_section_ids, :enrollment_ids, :assignment_ids, :group_ids
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
              def initialize(course, options = [])
         
     | 
| 
       7 
7 
     | 
    
         
             
                @course = course
         
     | 
| 
       8 
8 
     | 
    
         
             
                @account = course.account
         
     | 
| 
       9 
9 
     | 
    
         
             
                @options = options
         
     | 
| 
       10 
10 
     | 
    
         
             
                @batch = CoalescingPanda::CanvasBatch.create(context: course, status: "Queued")
         
     | 
| 
      
 11 
     | 
    
         
            +
                @course_section_ids = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                @enrollment_ids = []
         
     | 
| 
      
 13 
     | 
    
         
            +
                @assignment_ids = []
         
     | 
| 
      
 14 
     | 
    
         
            +
                @group_ids = []
         
     | 
| 
       11 
15 
     | 
    
         
             
              end
         
     | 
| 
       12 
16 
     | 
    
         | 
| 
       13 
17 
     | 
    
         
             
              def api_client
         
     | 
| 
         @@ -19,10 +23,11 @@ class CoalescingPanda::Workers::CourseMiner 
     | 
|
| 
       19 
23 
     | 
    
         
             
                  batch.update_attributes(status: "Started", percent_complete: 0)
         
     | 
| 
       20 
24 
     | 
    
         
             
                  SUPPORTED_MODELS.each_with_index do |model_key, index|
         
     | 
| 
       21 
25 
     | 
    
         
             
                    index += 1
         
     | 
| 
       22 
     | 
    
         
            -
                     
     | 
| 
      
 26 
     | 
    
         
            +
                    process_api_data(model_key.to_sym) if options.include?(model_key)
         
     | 
| 
       23 
27 
     | 
    
         
             
                    percent_complete = (index/(options.count.nonzero? || 1).to_f * 100).round(1)
         
     | 
| 
       24 
28 
     | 
    
         
             
                    batch.update_attributes(percent_complete: percent_complete)
         
     | 
| 
       25 
29 
     | 
    
         
             
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  delete_removed_records
         
     | 
| 
       26 
31 
     | 
    
         
             
                  batch.update_attributes(status: "Completed", percent_complete: 100)
         
     | 
| 
       27 
32 
     | 
    
         
             
                rescue => e
         
     | 
| 
       28 
33 
     | 
    
         
             
                  batch.update_attributes(status: "Error", message: e.message)
         
     | 
| 
         @@ -30,104 +35,143 @@ class CoalescingPanda::Workers::CourseMiner 
     | 
|
| 
       30 
35 
     | 
    
         
             
              end
         
     | 
| 
       31 
36 
     | 
    
         
             
              handle_asynchronously :start
         
     | 
| 
       32 
37 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
              def  
     | 
| 
      
 38 
     | 
    
         
            +
              def process_api_data(key)
         
     | 
| 
       34 
39 
     | 
    
         
             
                case key
         
     | 
| 
       35 
     | 
    
         
            -
                when :users
         
     | 
| 
       36 
     | 
    
         
            -
                  :list_course_users
         
     | 
| 
       37 
40 
     | 
    
         
             
                when :sections
         
     | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
      
 41 
     | 
    
         
            +
                  collection = api_client.course_sections(course.canvas_course_id).all_pages!
         
     | 
| 
      
 42 
     | 
    
         
            +
                  sync_sections(collection)
         
     | 
| 
      
 43 
     | 
    
         
            +
                when :users
         
     | 
| 
      
 44 
     | 
    
         
            +
                  collection = api_client.list_course_users(course.canvas_course_id).all_pages!
         
     | 
| 
      
 45 
     | 
    
         
            +
                  sync_users(collection)
         
     | 
| 
       39 
46 
     | 
    
         
             
                when :enrollments
         
     | 
| 
       40 
     | 
    
         
            -
                   
     | 
| 
      
 47 
     | 
    
         
            +
                  collection = api_client.course_enrollments(course.canvas_course_id).all_pages!
         
     | 
| 
      
 48 
     | 
    
         
            +
                  sync_enrollments(collection)
         
     | 
| 
       41 
49 
     | 
    
         
             
                when :assignments
         
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
      
 50 
     | 
    
         
            +
                  collection = api_client.assignments(course.canvas_course_id).all_pages!
         
     | 
| 
      
 51 
     | 
    
         
            +
                  sync_assignments(collection)
         
     | 
| 
       43 
52 
     | 
    
         
             
                when :submissions
         
     | 
| 
       44 
     | 
    
         
            -
                  :get_course_submissions
         
     | 
| 
       45 
     | 
    
         
            -
                when :groups
         
     | 
| 
       46 
     | 
    
         
            -
                  :course_groups
         
     | 
| 
       47 
     | 
    
         
            -
                when :group_memberships
         
     | 
| 
       48 
     | 
    
         
            -
                  :list_group_memberships
         
     | 
| 
       49 
     | 
    
         
            -
                else
         
     | 
| 
       50 
     | 
    
         
            -
                  raise "API METHOD DOESN'T EXIST"
         
     | 
| 
       51 
     | 
    
         
            -
                end
         
     | 
| 
       52 
     | 
    
         
            -
              end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
              def canvas_model_data(method, model_key)
         
     | 
| 
       55 
     | 
    
         
            -
                if model_key == :submissions
         
     | 
| 
       56 
53 
     | 
    
         
             
                  collection = []
         
     | 
| 
       57 
54 
     | 
    
         
             
                  course.assignments.each do |assignment|
         
     | 
| 
       58 
55 
     | 
    
         
             
                    api_client.get_course_submissions(course.canvas_course_id, assignment.canvas_assignment_id).all_pages!.each do |submissions|
         
     | 
| 
       59 
56 
     | 
    
         
             
                      collection << submissions
         
     | 
| 
       60 
57 
     | 
    
         
             
                    end
         
     | 
| 
       61 
58 
     | 
    
         
             
                  end
         
     | 
| 
       62 
     | 
    
         
            -
                   
     | 
| 
       63 
     | 
    
         
            -
                 
     | 
| 
      
 59 
     | 
    
         
            +
                  sync_submissions(collection)
         
     | 
| 
      
 60 
     | 
    
         
            +
                when :groups
         
     | 
| 
      
 61 
     | 
    
         
            +
                  collection = api_client.course_groups(course.canvas_course_id).all_pages!
         
     | 
| 
      
 62 
     | 
    
         
            +
                  sync_groups(collection)
         
     | 
| 
      
 63 
     | 
    
         
            +
                when :group_memberships
         
     | 
| 
       64 
64 
     | 
    
         
             
                  collection = []
         
     | 
| 
       65 
65 
     | 
    
         
             
                  course.groups.each do |group|
         
     | 
| 
       66 
66 
     | 
    
         
             
                    api_client.list_group_memberships(group.canvas_group_id).all_pages!.each do |group_memberships|
         
     | 
| 
       67 
67 
     | 
    
         
             
                      collection << group_memberships
         
     | 
| 
       68 
68 
     | 
    
         
             
                    end
         
     | 
| 
       69 
69 
     | 
    
         
             
                  end
         
     | 
| 
       70 
     | 
    
         
            -
                   
     | 
| 
      
 70 
     | 
    
         
            +
                  sync_group_memberships(collection)
         
     | 
| 
       71 
71 
     | 
    
         
             
                else
         
     | 
| 
       72 
     | 
    
         
            -
                   
     | 
| 
       73 
     | 
    
         
            -
                  create_records(collection, model_key)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  raise "API METHOD DOESN'T EXIST"
         
     | 
| 
       74 
73 
     | 
    
         
             
                end
         
     | 
| 
       75 
74 
     | 
    
         
             
              end
         
     | 
| 
       76 
75 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
              def  
     | 
| 
       78 
     | 
    
         
            -
                 
     | 
| 
      
 76 
     | 
    
         
            +
              def delete_removed_records
         
     | 
| 
      
 77 
     | 
    
         
            +
                course.sections.where.not(id: course_section_ids).destroy_all
         
     | 
| 
      
 78 
     | 
    
         
            +
                course.enrollments.where.not(id: enrollment_ids).destroy_all
         
     | 
| 
      
 79 
     | 
    
         
            +
                course.assignments.where.not(id: assignment_ids).destroy_all
         
     | 
| 
      
 80 
     | 
    
         
            +
                course.groups.where.not(id: group_ids).destroy_all
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              def sync_sections(collection)
         
     | 
| 
       79 
84 
     | 
    
         
             
                collection.each do |values|
         
     | 
| 
       80 
85 
     | 
    
         
             
                  begin
         
     | 
| 
       81 
     | 
    
         
            -
                     
     | 
| 
       82 
     | 
    
         
            -
                     
     | 
| 
       83 
     | 
    
         
            -
                     
     | 
| 
       84 
     | 
    
         
            -
                     
     | 
| 
       85 
     | 
    
         
            -
                     
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                    else
         
     | 
| 
       88 
     | 
    
         
            -
                      record = course.send(model_key).where("#{canvas_id_key} = ?", values['id'].to_s).first_or_initialize
         
     | 
| 
       89 
     | 
    
         
            -
                    end
         
     | 
| 
       90 
     | 
    
         
            -
                    record.coalescing_panda_lti_account_id = account.id if record.respond_to?(:coalescing_panda_lti_account_id)
         
     | 
| 
       91 
     | 
    
         
            -
                    record.assign_attributes(standard_attributes(record, values))
         
     | 
| 
       92 
     | 
    
         
            -
                    record.sis_id = sis_id(model_key, values) if record.respond_to?(:sis_id)
         
     | 
| 
       93 
     | 
    
         
            -
                    create_associations(record, model_key, values)
         
     | 
| 
       94 
     | 
    
         
            -
                    record.save(validate: false)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    values['course_section_id'] = values['id'].to_s
         
     | 
| 
      
 87 
     | 
    
         
            +
                    section = course.sections.where(canvas_section_id: values['course_section_id']).first_or_initialize
         
     | 
| 
      
 88 
     | 
    
         
            +
                    section.assign_attributes(standard_attributes(section, values))
         
     | 
| 
      
 89 
     | 
    
         
            +
                    section.sis_id = values['sis_section_id']
         
     | 
| 
      
 90 
     | 
    
         
            +
                    section.save(validate: false)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    course_section_ids << section.id
         
     | 
| 
       95 
92 
     | 
    
         
             
                  rescue => e
         
     | 
| 
       96 
     | 
    
         
            -
                    Rails.logger.error 
     | 
| 
      
 93 
     | 
    
         
            +
                    Rails.logger.error "Error syncing sections: #{e}"
         
     | 
| 
       97 
94 
     | 
    
         
             
                  end
         
     | 
| 
       98 
95 
     | 
    
         
             
                end
         
     | 
| 
       99 
96 
     | 
    
         
             
              end
         
     | 
| 
       100 
97 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
              def  
     | 
| 
       102 
     | 
    
         
            -
                 
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
              def sync_users(collection)
         
     | 
| 
      
 99 
     | 
    
         
            +
                collection.each do |values|
         
     | 
| 
      
 100 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 101 
     | 
    
         
            +
                    values['canvas_user_id'] = values["id"].to_s
         
     | 
| 
      
 102 
     | 
    
         
            +
                    user = account.users.where(canvas_user_id: values['canvas_user_id']).first_or_initialize
         
     | 
| 
      
 103 
     | 
    
         
            +
                    user.coalescing_panda_lti_account_id = account.id
         
     | 
| 
      
 104 
     | 
    
         
            +
                    user.assign_attributes(standard_attributes(user, values))
         
     | 
| 
      
 105 
     | 
    
         
            +
                    user.sis_id = values['sis_user_id'].to_s
         
     | 
| 
      
 106 
     | 
    
         
            +
                    user.save(validate: false)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 108 
     | 
    
         
            +
                    Rails.logger.error "Error syncing users: #{e}"
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
       105 
111 
     | 
    
         
             
              end
         
     | 
| 
       106 
112 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
              def  
     | 
| 
       108 
     | 
    
         
            -
                 
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
      
 113 
     | 
    
         
            +
              def sync_enrollments(collection)
         
     | 
| 
      
 114 
     | 
    
         
            +
                collection.each do |values|
         
     | 
| 
      
 115 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 116 
     | 
    
         
            +
                    values['canvas_enrollment_id'] = values['id'].to_s
         
     | 
| 
      
 117 
     | 
    
         
            +
                    enrollment = course.enrollments.where(canvas_enrollment_id: values['canvas_enrollment_id']).first_or_initialize
         
     | 
| 
      
 118 
     | 
    
         
            +
                    enrollment.section = course.sections.find_by(canvas_section_id: values['course_section_id'].to_s)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    enrollment.user = account.users.find_by(canvas_user_id: values['user_id'].to_s)
         
     | 
| 
      
 120 
     | 
    
         
            +
                    values['workflow_state'] = values["enrollment_state"]
         
     | 
| 
      
 121 
     | 
    
         
            +
                    enrollment.assign_attributes(standard_attributes(enrollment, values))
         
     | 
| 
      
 122 
     | 
    
         
            +
                    enrollment.save(validate: false)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    enrollment_ids << enrollment.id
         
     | 
| 
      
 124 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 125 
     | 
    
         
            +
                    Rails.logger.error "Error syncing enrollments: #{e}"
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
       112 
128 
     | 
    
         
             
              end
         
     | 
| 
       113 
129 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
              def  
     | 
| 
       115 
     | 
    
         
            -
                 
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
                   
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                   
     | 
| 
       120 
     | 
    
         
            -
                   
     | 
| 
       121 
     | 
    
         
            -
                 
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
                   
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
                   
     | 
| 
       130 
     | 
    
         
            -
                   
     | 
| 
      
 130 
     | 
    
         
            +
              def sync_assignments(collection)
         
     | 
| 
      
 131 
     | 
    
         
            +
                collection.each do |values|
         
     | 
| 
      
 132 
     | 
    
         
            +
                  values['canvas_assignment_id'] = values['id'].to_s
         
     | 
| 
      
 133 
     | 
    
         
            +
                  assignment = course.assignments.where(canvas_assignment_id: values['canvas_assignment_id']).first_or_initialize
         
     | 
| 
      
 134 
     | 
    
         
            +
                  assignment.assign_attributes(standard_attributes(assignment, values))
         
     | 
| 
      
 135 
     | 
    
         
            +
                  assignment.save(validate: false)
         
     | 
| 
      
 136 
     | 
    
         
            +
                  assignment_ids << assignment.id
         
     | 
| 
      
 137 
     | 
    
         
            +
                end
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
              def sync_submissions(collection)
         
     | 
| 
      
 141 
     | 
    
         
            +
                collection.each do |values|
         
     | 
| 
      
 142 
     | 
    
         
            +
                  values['canvas_submission_id'] = values['id'].to_s
         
     | 
| 
      
 143 
     | 
    
         
            +
                  submission = course.submissions.where(canvas_submission_id: values['canvas_submission_id']).first_or_initialize
         
     | 
| 
      
 144 
     | 
    
         
            +
                  submission.user = course.users.find_by(canvas_user_id: values['user_id'].to_s)
         
     | 
| 
      
 145 
     | 
    
         
            +
                  submission.assignment = course.assignments.find_by(canvas_assignment_id: values['assignment_id'].to_s)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  submission.assign_attributes(standard_attributes(submission, values))
         
     | 
| 
      
 147 
     | 
    
         
            +
                  submission.save(validate: false)
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              def sync_groups(collection)
         
     | 
| 
      
 152 
     | 
    
         
            +
                collection.each do |values|
         
     | 
| 
      
 153 
     | 
    
         
            +
                  values['canvas_group_id'] = values['id'].to_s
         
     | 
| 
      
 154 
     | 
    
         
            +
                  group = course.groups.where(canvas_group_id: values['canvas_group_id']).first_or_initialize
         
     | 
| 
      
 155 
     | 
    
         
            +
                  group.assign_attributes(standard_attributes(group, values))
         
     | 
| 
      
 156 
     | 
    
         
            +
                  group.save(validate: false)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  group_ids << group.id
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
              end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              def sync_group_memberships(collection)
         
     | 
| 
      
 162 
     | 
    
         
            +
                collection.each do |values|
         
     | 
| 
      
 163 
     | 
    
         
            +
                  values['canvas_group_membership_id'] = values['id'].to_s
         
     | 
| 
      
 164 
     | 
    
         
            +
                  group_membership = course.group_memberships.where(canvas_group_membership_id: values['canvas_group_membership_id']).first_or_initialize
         
     | 
| 
      
 165 
     | 
    
         
            +
                  group_membership.group = course.groups.find_by(canvas_group_id: values['group_id'].to_s)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  group_membership.user = course.users.find_by(canvas_user_id: values['user_id'].to_s)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  group_membership.assign_attributes(standard_attributes(group_membership, values))
         
     | 
| 
      
 168 
     | 
    
         
            +
                  group_membership.save(validate: false)
         
     | 
| 
       131 
169 
     | 
    
         
             
                end
         
     | 
| 
       132 
170 
     | 
    
         
             
              end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
              def standard_attributes(record, attributes)
         
     | 
| 
      
 173 
     | 
    
         
            +
                new_attributes = attributes.dup
         
     | 
| 
      
 174 
     | 
    
         
            +
                new_attributes.delete('id')
         
     | 
| 
      
 175 
     | 
    
         
            +
                new_attributes.delete_if { |key, value| !record.attributes.include?(key) }
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
       133 
177 
     | 
    
         
             
            end
         
     | 
| 
         @@ -14,8 +14,9 @@ describe CoalescingPanda::LtiController, :type => :controller do 
     | 
|
| 
       14 
14 
     | 
    
         
             
                end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                it 'generates lti nav config' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  pending('cannot figure out why url: "test" is not working.')
         
     | 
| 
       17 
18 
     | 
    
         
             
                  CoalescingPanda.stage_navigation(:account, {
         
     | 
| 
       18 
     | 
    
         
            -
                    url: ' 
     | 
| 
      
 19 
     | 
    
         
            +
                    url: 'launch',
         
     | 
| 
       19 
20 
     | 
    
         
             
                    text: 'My Title',
         
     | 
| 
       20 
21 
     | 
    
         
             
                    enabled: false
         
     | 
| 
       21 
22 
     | 
    
         
             
                  })
         
     | 
| 
         @@ -30,10 +31,4 @@ describe CoalescingPanda::LtiController, :type => :controller do 
     | 
|
| 
       30 
31 
     | 
    
         
             
                end
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
              end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
              it 'get the url, from the action string' do
         
     | 
| 
       35 
     | 
    
         
            -
                options = controller.send(:ext_params, {url:'test_action'})
         
     | 
| 
       36 
     | 
    
         
            -
                options[:url].should == 'foo'
         
     | 
| 
       37 
     | 
    
         
            -
              end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
34 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,13 +2,16 @@ require 'spec_helper' 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            describe CoalescingPanda::Oauth2Controller, :type => :controller do
         
     | 
| 
       4 
4 
     | 
    
         
             
              routes { CoalescingPanda::Engine.routes }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:account) { FactoryGirl.create(:account, settings: {base_url: 'foo.com'}) }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:user) { FactoryGirl.create(:user, account: account) }
         
     | 
| 
       5 
7 
     | 
    
         | 
| 
       6 
8 
     | 
    
         
             
              describe "#redirect" do
         
     | 
| 
       7 
9 
     | 
    
         
             
                it 'creates a token in the db' do
         
     | 
| 
       8 
10 
     | 
    
         
             
                  ENV['OAUTH_PROTOCOL'] = 'http'
         
     | 
| 
       9 
11 
     | 
    
         
             
                  Bearcat::Client.any_instance.stub(retrieve_token: 'foobar')
         
     | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
      
 12 
     | 
    
         
            +
                  session[:state] = 'test'
         
     | 
| 
      
 13 
     | 
    
         
            +
                  get :redirect, {user_id: user.id, api_domain: 'foo.com', code: 'bar', key: account.key, state: 'test'}
         
     | 
| 
      
 14 
     | 
    
         
            +
                  auth = CoalescingPanda::CanvasApiAuth.find_by_user_id_and_api_domain(user.id, 'foo.com')
         
     | 
| 
       12 
15 
     | 
    
         
             
                  auth.should_not == nil
         
     | 
| 
       13 
16 
     | 
    
         
             
                end
         
     | 
| 
       14 
17 
     | 
    
         | 
| 
         @@ -16,7 +19,6 @@ describe CoalescingPanda::Oauth2Controller, :type => :controller do 
     | 
|
| 
       16 
19 
     | 
    
         
             
                  get :redirect, {error: 'your face'}
         
     | 
| 
       17 
20 
     | 
    
         
             
                  CoalescingPanda::CanvasApiAuth.all.count.should == 0
         
     | 
| 
       18 
21 
     | 
    
         
             
                end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
22 
     | 
    
         
             
              end
         
     | 
| 
       21 
23 
     | 
    
         | 
| 
       22 
24 
     | 
    
         
             
            end
         
     | 
    
        data/spec/dummy/db/schema.rb
    CHANGED
    
    | 
         @@ -11,14 +11,13 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            #
         
     | 
| 
       12 
12 
     | 
    
         
             
            # It's strongly recommended that you check this file into your version control system.
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
            ActiveRecord::Schema.define(version:  
     | 
| 
      
 14 
     | 
    
         
            +
            ActiveRecord::Schema.define(version: 20150210180516) do
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
              create_table "coalescing_panda_assignments", force: true do |t|
         
     | 
| 
       17 
     | 
    
         
            -
                t.integer  "coalescing_panda_course_id"
         
     | 
| 
      
 17 
     | 
    
         
            +
                t.integer  "coalescing_panda_course_id",        null: false
         
     | 
| 
       18 
18 
     | 
    
         
             
                t.string   "name"
         
     | 
| 
       19 
     | 
    
         
            -
                t. 
     | 
| 
       20 
     | 
    
         
            -
                t.string   "canvas_assignment_id"
         
     | 
| 
       21 
     | 
    
         
            -
                t.string   "sis_id"
         
     | 
| 
      
 19 
     | 
    
         
            +
                t.text     "description"
         
     | 
| 
      
 20 
     | 
    
         
            +
                t.string   "canvas_assignment_id",              null: false
         
     | 
| 
       22 
21 
     | 
    
         
             
                t.string   "workflow_state"
         
     | 
| 
       23 
22 
     | 
    
         
             
                t.float    "points_possible"
         
     | 
| 
       24 
23 
     | 
    
         
             
                t.datetime "due_at"
         
     | 
| 
         @@ -32,10 +31,7 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       32 
31 
     | 
    
         
             
                t.boolean  "published"
         
     | 
| 
       33 
32 
     | 
    
         
             
              end
         
     | 
| 
       34 
33 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
              add_index "coalescing_panda_assignments", ["canvas_assignment_id"], name: " 
     | 
| 
       36 
     | 
    
         
            -
              add_index "coalescing_panda_assignments", ["coalescing_panda_course_id"], name: "index_assignment_course_id"
         
     | 
| 
       37 
     | 
    
         
            -
              add_index "coalescing_panda_assignments", ["coalescing_panda_course_id"], name: "index_assignments_course"
         
     | 
| 
       38 
     | 
    
         
            -
              add_index "coalescing_panda_assignments", ["sis_id"], name: "index_coalescing_panda_assignments_on_sis_id"
         
     | 
| 
      
 34 
     | 
    
         
            +
              add_index "coalescing_panda_assignments", ["coalescing_panda_course_id", "canvas_assignment_id"], name: "index_assignments_course", unique: true
         
     | 
| 
       39 
35 
     | 
    
         | 
| 
       40 
36 
     | 
    
         
             
              create_table "coalescing_panda_canvas_api_auths", force: true do |t|
         
     | 
| 
       41 
37 
     | 
    
         
             
                t.string   "user_id"
         
     | 
| 
         @@ -51,15 +47,15 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       51 
47 
     | 
    
         
             
                t.text     "message"
         
     | 
| 
       52 
48 
     | 
    
         
             
                t.datetime "created_at"
         
     | 
| 
       53 
49 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       54 
     | 
    
         
            -
                t. 
     | 
| 
      
 50 
     | 
    
         
            +
                t.integer  "context_id"
         
     | 
| 
       55 
51 
     | 
    
         
             
                t.string   "context_type"
         
     | 
| 
       56 
52 
     | 
    
         
             
              end
         
     | 
| 
       57 
53 
     | 
    
         | 
| 
       58 
54 
     | 
    
         
             
              create_table "coalescing_panda_courses", force: true do |t|
         
     | 
| 
       59 
     | 
    
         
            -
                t.integer  "coalescing_panda_lti_account_id"
         
     | 
| 
      
 55 
     | 
    
         
            +
                t.integer  "coalescing_panda_lti_account_id", null: false
         
     | 
| 
       60 
56 
     | 
    
         
             
                t.integer  "coalescing_panda_term_id"
         
     | 
| 
       61 
57 
     | 
    
         
             
                t.string   "name"
         
     | 
| 
       62 
     | 
    
         
            -
                t.string   "canvas_course_id"
         
     | 
| 
      
 58 
     | 
    
         
            +
                t.string   "canvas_course_id",                null: false
         
     | 
| 
       63 
59 
     | 
    
         
             
                t.string   "sis_id"
         
     | 
| 
       64 
60 
     | 
    
         
             
                t.datetime "start_at"
         
     | 
| 
       65 
61 
     | 
    
         
             
                t.datetime "conclude_at"
         
     | 
| 
         @@ -69,29 +65,24 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       69 
65 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       70 
66 
     | 
    
         
             
              end
         
     | 
| 
       71 
67 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
              add_index "coalescing_panda_courses", ["canvas_course_id"], name: " 
     | 
| 
       73 
     | 
    
         
            -
              add_index "coalescing_panda_courses", [" 
     | 
| 
       74 
     | 
    
         
            -
              add_index "coalescing_panda_courses", ["coalescing_panda_lti_account_id"], name: "index_courses_lti_account_id"
         
     | 
| 
       75 
     | 
    
         
            -
              add_index "coalescing_panda_courses", ["coalescing_panda_term_id"], name: "index_courses_term"
         
     | 
| 
       76 
     | 
    
         
            -
              add_index "coalescing_panda_courses", ["coalescing_panda_term_id"], name: "index_courses_term_id"
         
     | 
| 
      
 68 
     | 
    
         
            +
              add_index "coalescing_panda_courses", ["coalescing_panda_lti_account_id", "canvas_course_id"], name: "index_courses_account", unique: true
         
     | 
| 
      
 69 
     | 
    
         
            +
              add_index "coalescing_panda_courses", ["coalescing_panda_term_id", "canvas_course_id"], name: "index_courses_term", unique: true
         
     | 
| 
       77 
70 
     | 
    
         
             
              add_index "coalescing_panda_courses", ["sis_id"], name: "index_coalescing_panda_courses_on_sis_id"
         
     | 
| 
       78 
71 
     | 
    
         | 
| 
       79 
72 
     | 
    
         
             
              create_table "coalescing_panda_enrollments", force: true do |t|
         
     | 
| 
       80 
     | 
    
         
            -
                t.integer  "coalescing_panda_user_id"
         
     | 
| 
       81 
     | 
    
         
            -
                t.integer  "coalescing_panda_section_id"
         
     | 
| 
      
 73 
     | 
    
         
            +
                t.integer  "coalescing_panda_user_id",    null: false
         
     | 
| 
      
 74 
     | 
    
         
            +
                t.integer  "coalescing_panda_section_id", null: false
         
     | 
| 
       82 
75 
     | 
    
         
             
                t.string   "workflow_state"
         
     | 
| 
       83 
76 
     | 
    
         
             
                t.string   "sis_id"
         
     | 
| 
       84 
     | 
    
         
            -
                t.string   "canvas_enrollment_id"
         
     | 
| 
      
 77 
     | 
    
         
            +
                t.string   "canvas_enrollment_id",        null: false
         
     | 
| 
      
 78 
     | 
    
         
            +
                t.string   "enrollment_type"
         
     | 
| 
       85 
79 
     | 
    
         
             
                t.datetime "start_at"
         
     | 
| 
       86 
80 
     | 
    
         
             
                t.datetime "end_at"
         
     | 
| 
       87 
81 
     | 
    
         
             
                t.datetime "created_at"
         
     | 
| 
       88 
82 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       89 
83 
     | 
    
         
             
              end
         
     | 
| 
       90 
84 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
              add_index "coalescing_panda_enrollments", [" 
     | 
| 
       92 
     | 
    
         
            -
              add_index "coalescing_panda_enrollments", ["coalescing_panda_section_id"], name: "index_enrollments_section_id"
         
     | 
| 
       93 
     | 
    
         
            -
              add_index "coalescing_panda_enrollments", ["coalescing_panda_user_id", "coalescing_panda_section_id"], name: "index_enrollments_user_and_assignment"
         
     | 
| 
       94 
     | 
    
         
            -
              add_index "coalescing_panda_enrollments", ["coalescing_panda_user_id"], name: "index_enrollments_user_id"
         
     | 
| 
      
 85 
     | 
    
         
            +
              add_index "coalescing_panda_enrollments", ["coalescing_panda_user_id", "coalescing_panda_section_id", "enrollment_type"], name: "index_enrollments_user_and_section", unique: true
         
     | 
| 
       95 
86 
     | 
    
         
             
              add_index "coalescing_panda_enrollments", ["sis_id"], name: "index_coalescing_panda_enrollments_on_sis_id"
         
     | 
| 
       96 
87 
     | 
    
         | 
| 
       97 
88 
     | 
    
         
             
              create_table "coalescing_panda_group_memberships", force: true do |t|
         
     | 
| 
         @@ -103,9 +94,6 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       103 
94 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       104 
95 
     | 
    
         
             
              end
         
     | 
| 
       105 
96 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
              add_index "coalescing_panda_group_memberships", ["coalescing_panda_group_id"], name: "index_memberships_group_id"
         
     | 
| 
       107 
     | 
    
         
            -
              add_index "coalescing_panda_group_memberships", ["coalescing_panda_user_id"], name: "index_memberships_user_id"
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
97 
     | 
    
         
             
              create_table "coalescing_panda_groups", force: true do |t|
         
     | 
| 
       110 
98 
     | 
    
         
             
                t.integer  "context_id"
         
     | 
| 
       111 
99 
     | 
    
         
             
                t.string   "context_type"
         
     | 
| 
         @@ -124,10 +112,10 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       124 
112 
     | 
    
         
             
                t.string   "secret"
         
     | 
| 
       125 
113 
     | 
    
         
             
                t.string   "oauth2_client_id"
         
     | 
| 
       126 
114 
     | 
    
         
             
                t.string   "oauth2_client_key"
         
     | 
| 
      
 115 
     | 
    
         
            +
                t.string   "canvas_account_id"
         
     | 
| 
      
 116 
     | 
    
         
            +
                t.text     "settings"
         
     | 
| 
       127 
117 
     | 
    
         
             
                t.datetime "created_at"
         
     | 
| 
       128 
118 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       129 
     | 
    
         
            -
                t.text     "settings"
         
     | 
| 
       130 
     | 
    
         
            -
                t.string   "canvas_account_id"
         
     | 
| 
       131 
119 
     | 
    
         
             
              end
         
     | 
| 
       132 
120 
     | 
    
         | 
| 
       133 
121 
     | 
    
         
             
              create_table "coalescing_panda_lti_nonces", force: true do |t|
         
     | 
| 
         @@ -137,9 +125,9 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       137 
125 
     | 
    
         
             
              end
         
     | 
| 
       138 
126 
     | 
    
         | 
| 
       139 
127 
     | 
    
         
             
              create_table "coalescing_panda_sections", force: true do |t|
         
     | 
| 
       140 
     | 
    
         
            -
                t.integer  "coalescing_panda_course_id"
         
     | 
| 
      
 128 
     | 
    
         
            +
                t.integer  "coalescing_panda_course_id", null: false
         
     | 
| 
       141 
129 
     | 
    
         
             
                t.string   "name"
         
     | 
| 
       142 
     | 
    
         
            -
                t.string   "canvas_section_id"
         
     | 
| 
      
 130 
     | 
    
         
            +
                t.string   "canvas_section_id",          null: false
         
     | 
| 
       143 
131 
     | 
    
         
             
                t.string   "sis_id"
         
     | 
| 
       144 
132 
     | 
    
         
             
                t.string   "workflow_state"
         
     | 
| 
       145 
133 
     | 
    
         
             
                t.datetime "start_at"
         
     | 
| 
         @@ -148,9 +136,7 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       148 
136 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       149 
137 
     | 
    
         
             
              end
         
     | 
| 
       150 
138 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
              add_index "coalescing_panda_sections", ["canvas_section_id"], name: " 
     | 
| 
       152 
     | 
    
         
            -
              add_index "coalescing_panda_sections", ["coalescing_panda_course_id"], name: "index_coalescing_panda_sections_on_coalescing_panda_course_id"
         
     | 
| 
       153 
     | 
    
         
            -
              add_index "coalescing_panda_sections", ["coalescing_panda_course_id"], name: "index_sections_course_id"
         
     | 
| 
      
 139 
     | 
    
         
            +
              add_index "coalescing_panda_sections", ["coalescing_panda_course_id", "canvas_section_id"], name: "index_sections_course", unique: true
         
     | 
| 
       154 
140 
     | 
    
         
             
              add_index "coalescing_panda_sections", ["sis_id"], name: "index_coalescing_panda_sections_on_sis_id"
         
     | 
| 
       155 
141 
     | 
    
         | 
| 
       156 
142 
     | 
    
         
             
              create_table "coalescing_panda_sessions", force: true do |t|
         
     | 
| 
         @@ -161,29 +147,27 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       161 
147 
     | 
    
         
             
              end
         
     | 
| 
       162 
148 
     | 
    
         | 
| 
       163 
149 
     | 
    
         
             
              create_table "coalescing_panda_submissions", force: true do |t|
         
     | 
| 
       164 
     | 
    
         
            -
                t.integer  "coalescing_panda_user_id"
         
     | 
| 
       165 
     | 
    
         
            -
                t.integer  "coalescing_panda_assignment_id"
         
     | 
| 
      
 150 
     | 
    
         
            +
                t.integer  "coalescing_panda_user_id",       null: false
         
     | 
| 
      
 151 
     | 
    
         
            +
                t.integer  "coalescing_panda_assignment_id", null: false
         
     | 
| 
       166 
152 
     | 
    
         
             
                t.string   "url"
         
     | 
| 
       167 
153 
     | 
    
         
             
                t.string   "grade"
         
     | 
| 
       168 
154 
     | 
    
         
             
                t.string   "score"
         
     | 
| 
       169 
155 
     | 
    
         
             
                t.datetime "submitted_at"
         
     | 
| 
       170 
156 
     | 
    
         
             
                t.string   "workflow_state"
         
     | 
| 
       171 
     | 
    
         
            -
                t.string   "canvas_submission_id"
         
     | 
| 
      
 157 
     | 
    
         
            +
                t.string   "canvas_submission_id",           null: false
         
     | 
| 
       172 
158 
     | 
    
         
             
                t.datetime "created_at"
         
     | 
| 
       173 
159 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       174 
160 
     | 
    
         
             
              end
         
     | 
| 
       175 
161 
     | 
    
         | 
| 
       176 
162 
     | 
    
         
             
              add_index "coalescing_panda_submissions", ["canvas_submission_id"], name: "index_coalescing_panda_submissions_on_canvas_submission_id"
         
     | 
| 
       177 
     | 
    
         
            -
              add_index "coalescing_panda_submissions", ["coalescing_panda_assignment_id"], name: " 
     | 
| 
       178 
     | 
    
         
            -
              add_index "coalescing_panda_submissions", ["coalescing_panda_user_id", "coalescing_panda_assignment_id"], name: "index_submissions_user_and_assignment"
         
     | 
| 
       179 
     | 
    
         
            -
              add_index "coalescing_panda_submissions", ["coalescing_panda_user_id"], name: "index_submissions_user_id"
         
     | 
| 
      
 163 
     | 
    
         
            +
              add_index "coalescing_panda_submissions", ["coalescing_panda_user_id", "coalescing_panda_assignment_id", "canvas_submission_id"], name: "index_submissions_user_and_assignment", unique: true
         
     | 
| 
       180 
164 
     | 
    
         | 
| 
       181 
165 
     | 
    
         
             
              create_table "coalescing_panda_terms", force: true do |t|
         
     | 
| 
       182 
     | 
    
         
            -
                t.integer  "coalescing_panda_lti_account_id"
         
     | 
| 
      
 166 
     | 
    
         
            +
                t.integer  "coalescing_panda_lti_account_id", null: false
         
     | 
| 
       183 
167 
     | 
    
         
             
                t.string   "name"
         
     | 
| 
       184 
168 
     | 
    
         
             
                t.string   "code"
         
     | 
| 
       185 
169 
     | 
    
         
             
                t.string   "sis_id"
         
     | 
| 
       186 
     | 
    
         
            -
                t.string   "canvas_term_id"
         
     | 
| 
      
 170 
     | 
    
         
            +
                t.string   "canvas_term_id",                  null: false
         
     | 
| 
       187 
171 
     | 
    
         
             
                t.datetime "start_at"
         
     | 
| 
       188 
172 
     | 
    
         
             
                t.datetime "end_at"
         
     | 
| 
       189 
173 
     | 
    
         
             
                t.string   "workflow_state"
         
     | 
| 
         @@ -191,25 +175,22 @@ ActiveRecord::Schema.define(version: 20150218185536) do 
     | 
|
| 
       191 
175 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       192 
176 
     | 
    
         
             
              end
         
     | 
| 
       193 
177 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
              add_index "coalescing_panda_terms", ["canvas_term_id"], name: " 
     | 
| 
       195 
     | 
    
         
            -
              add_index "coalescing_panda_terms", ["coalescing_panda_lti_account_id"], name: "index_terms_lti_account_id"
         
     | 
| 
      
 178 
     | 
    
         
            +
              add_index "coalescing_panda_terms", ["canvas_term_id", "coalescing_panda_lti_account_id"], name: "index_terms_account", unique: true
         
     | 
| 
       196 
179 
     | 
    
         
             
              add_index "coalescing_panda_terms", ["sis_id"], name: "index_coalescing_panda_terms_on_sis_id"
         
     | 
| 
       197 
180 
     | 
    
         | 
| 
       198 
181 
     | 
    
         
             
              create_table "coalescing_panda_users", force: true do |t|
         
     | 
| 
       199 
     | 
    
         
            -
                t.integer  "coalescing_panda_lti_account_id"
         
     | 
| 
      
 182 
     | 
    
         
            +
                t.integer  "coalescing_panda_lti_account_id", null: false
         
     | 
| 
       200 
183 
     | 
    
         
             
                t.string   "name"
         
     | 
| 
       201 
184 
     | 
    
         
             
                t.string   "email"
         
     | 
| 
       202 
185 
     | 
    
         
             
                t.string   "roles"
         
     | 
| 
       203 
186 
     | 
    
         
             
                t.string   "workflow_state"
         
     | 
| 
       204 
187 
     | 
    
         
             
                t.string   "sis_id"
         
     | 
| 
       205 
     | 
    
         
            -
                t.string   "canvas_user_id"
         
     | 
| 
      
 188 
     | 
    
         
            +
                t.string   "canvas_user_id",                  null: false
         
     | 
| 
       206 
189 
     | 
    
         
             
                t.datetime "created_at"
         
     | 
| 
       207 
190 
     | 
    
         
             
                t.datetime "updated_at"
         
     | 
| 
       208 
191 
     | 
    
         
             
              end
         
     | 
| 
       209 
192 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
              add_index "coalescing_panda_users", ["canvas_user_id"], name: " 
     | 
| 
       211 
     | 
    
         
            -
              add_index "coalescing_panda_users", ["coalescing_panda_lti_account_id"], name: "index_users_account"
         
     | 
| 
       212 
     | 
    
         
            -
              add_index "coalescing_panda_users", ["coalescing_panda_lti_account_id"], name: "index_users_lti_account_id"
         
     | 
| 
      
 193 
     | 
    
         
            +
              add_index "coalescing_panda_users", ["coalescing_panda_lti_account_id", "canvas_user_id"], name: "index_users_account", unique: true
         
     | 
| 
       213 
194 
     | 
    
         
             
              add_index "coalescing_panda_users", ["sis_id"], name: "index_coalescing_panda_users_on_sis_id"
         
     | 
| 
       214 
195 
     | 
    
         | 
| 
       215 
196 
     | 
    
         
             
              create_table "delayed_jobs", force: true do |t|
         
     | 
    
        data/spec/dummy/db/test.sqlite3
    CHANGED
    
    | 
         Binary file 
     |