░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
pplmvsvm
LOCATION:
/var/www/canvas/spec/models/microsoft_sync
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: group_spec.rb
# frozen_string_literal: true # # Copyright (C) 2015 - 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/>. describe MicrosoftSync::Group do subject { described_class.create(course: course_model) } it { is_expected.to be_a(described_class) } it { is_expected.to be_valid } it { is_expected.to belong_to(:course).required } it { is_expected.to belong_to(:last_error_report).class_name("ErrorReport") } it { is_expected.to validate_presence_of(:course) } it "defaults to workflow_state=pending" do expect(subject.workflow_state).to eq("pending") end it "is soft deleted" do subject.destroy! expect(subject.reload).to be_deleted end describe "not_deleted scope" do subject { described_class.not_deleted } before(:once) do %i[pending running errored completed deleted].each do |state| course_model.create_microsoft_sync_group(workflow_state: state) end end it "includes pending groups" do expect(subject.where(workflow_state: "pending")).not_to be_blank end it "includes running groups" do expect(subject.where(workflow_state: "running")).not_to be_blank end it "includes errored groups" do expect(subject.where(workflow_state: "errored")).not_to be_blank end it "includes completed groups" do expect(subject.where(workflow_state: "completed")).not_to be_blank end it "does not include deleted groups" do expect(subject.where(workflow_state: "deleted")).to be_blank end end describe "#manual_sync_cooldown" do it "returns the cool down Setting value" do expect(described_class.manual_sync_cooldown).to eq( Setting.get("msft_sync.manual_sync_cooldown", 90.minutes.to_s).to_i ) end end describe "#restore!" do context "with a deleted group" do subject do group = super() group.destroy! group.restore! group end it "resets the job state to {restored: true}" do expect(subject.job_state).to eq(restored: true) end it "resets the last error" do expect(subject.last_error).to be_nil end it "resets the workflow state" do expect(subject.workflow_state).to eq "pending" end end context "with an non-deleted group" do subject do group = super() group.update!(workflow_state: "running") group.restore! group end it "does nothing" do expect(subject.workflow_state).to eq "running" end end end describe "#update_unless_deleted" do def run_method! subject.update_unless_deleted(workflow_state: "errored", job_state: { abc: true }) end context "when state is deleted in the database" do before do described_class.where(id: subject.id).update_all(workflow_state: "deleted") end it { expect(run_method!).to be(false) } it 'updates the workflow_state on the object to match the "deleted" in the DB' do expect { run_method! }.to change { subject.workflow_state }.from("pending").to("deleted") end it "does not update the workflow_state in the DB" do expect { run_method! }.to_not change { described_class.find(subject.id).workflow_state }.from("deleted") end it "does not update the extra attributes in the DB" do expect { run_method! }.to_not change { described_class.find(subject.id).job_state }.from(nil) end it "does not update the extra attributes on the object" do expect { run_method! }.to_not change { subject.job_state }.from(nil) end end context "when state is not deleted" do it { expect(run_method!).to be(true) } it "updates the workflow_state on the object" do expect { run_method! }.to change { subject.workflow_state }.from("pending").to("errored") end it "updates the workflow_state in the DB" do expect { run_method! }.to change { described_class.find(subject.id).workflow_state }.from("pending").to("errored") end it "updates the extra attributes in the DB" do expect { run_method! }.to change { described_class.find(subject.id).job_state }.from(nil).to(abc: true) end it "updates the extra attributes on the object" do expect { run_method! }.to change { subject.job_state }.from(nil).to(abc: true) end end end describe "#job_state" do it "serializes TimeWithZone objects, symbols, and complex data structures" do time = 1.minute.from_now subject.job_state = { a: { "b" => time } } subject.save expect(described_class.find(subject.id).job_state).to eq(a: { "b" => time }) end end describe "#syncer_job" do it "creates a StateMachineJob with Syncer as the steps" do syncer_job = subject.syncer_job expect(syncer_job).to be_a(MicrosoftSync::StateMachineJob) expect(syncer_job.job_state_record).to eq(subject) expect(syncer_job.steps_object).to be_a(MicrosoftSync::SyncerSteps) expect(syncer_job.steps_object.group).to eq(subject) end end describe "#enqueue_future_sync" do let(:delay_double) { double(:delay) } let(:syncer_job) { double(:syncer_job) } it "enqueues a debounced (singleton and on_conflict=overwrite) job" do Timecop.freeze do expect(subject).to receive(:syncer_job).and_return(syncer_job) expect(syncer_job).to receive(:delay).with( singleton: "#{described_class.name}:#{subject.global_id}:enqueue_future_sync", # Using a different default value for the setting here will test the code uses the same one run_at: Setting.get("microsoft_group_enrollments_syncing_debounce_minutes", 123) .to_i.minutes.from_now, on_conflict: :overwrite ).and_return(delay_double) expect(delay_double).to receive(:run_later).with(no_args) subject.enqueue_future_sync end end context "when the MicrosoftSync::Group is in the deleted state" do it "does not enqueue a job" do subject.destroy expect(subject).to_not receive(:syncer_job) subject.enqueue_future_sync end end end describe "#enqueue_future_partial_sync" do let(:delay_double) { double(:delay) } let(:syncer_job) { double(:syncer_job) } it "upserts the sync change & enqueues a debounced (singleton and on_conflict=overwrite) job" do Timecop.freeze do enrollment = double(:enrollment) expect(MicrosoftSync::PartialSyncChange).to receive(:upsert_for_enrollment).with(enrollment) expect(subject).to receive(:syncer_job).and_return(syncer_job) expect(syncer_job).to receive(:delay).with( singleton: "#{described_class.name}:#{subject.global_id}:enqueue_future_partial_sync", run_at: Setting.get("microsoft_group_enrollments_partial_syncing_debounce_minutes", 123) .to_i.minutes.from_now, on_conflict: :overwrite ).and_return(delay_double) expect(delay_double).to receive(:run_later).with(:partial) subject.enqueue_future_partial_sync(enrollment) end end context "when the MicrosoftSync::Group is in the deleted state" do it "does not upsert a sync change or enqueue a job" do subject.destroy expect(MicrosoftSync::PartialSyncChange).to_not receive(:upsert_for_enrollment) expect(subject).to_not receive(:syncer_job) subject.enqueue_future_partial_sync(double(:enrollment)) end end end end
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 group_spec.rb
RB
8.1 KB
2023-09-24 03:36
EDIT
📄 partial_sync_change_spec.rb
RB
7.1 KB
2023-09-24 03:36
EDIT
📄 user_mapping_spec.rb
RB
13.4 KB
2023-09-24 03:36
EDIT