class Chook::TestSubject

A subject that will be used with a TestEvent class, to be sent to a Webhook server, simulating one from the JSS.

This is the parent class to all classes in the Chook::TestSubjects module.

All constants, methods, and attributes that are common to TestSubject classes are defined here.

Public Class Methods

generate_classes() click to toggle source

Dynamically generate the varios subclasses to TestSubject and store them in the TestSubjects module.

# File lib/chook/subject/test_subject.rb, line 40
def self.generate_classes
  Chook::Subject.classes.each do |classname, attribs|
    # Don't redefine anything.
    next if Chook::TestSubjects.const_defined? classname

    # new subclass of Chook::TestSubject
    new_class = Class.new(Chook::TestSubject) do
      # add getter, setters, validators for all the attribs.
      attribs.each do |attrib, deets|
        # getter
        attr_reader attrib
        validator = deets[:validation]

        # setter with validator
        define_method("#{attrib}=") do |new_val|
          if validator.is_a? Class
            raise "Invalid value for #{attrib}, must be a #{validator}" unless new_val.is_a? validator
          elsif !validator.nil?
            raise "Invalid value for #{attrib}" unless Chook::Validators.send validator, new_val
          end
          instance_variable_set(('@' + attrib.to_s), new_val)
        end # end define method
      end # end do |attrib, deets|
    end # end new_class
    # set a class constant so each class knows it's name
    new_class.const_set Chook::Subject::NAME_CONSTANT, classname

    # add the class to the Chook::TestSubjects module
    Chook::TestSubjects.const_set classname, new_class
  end # end Chook::Subject.classes.each do |classname, attribs|
end
new(subject_data = nil) click to toggle source

All the subclassses will inherit this constructor

The argument is a Hash with keys from the appropriate keys defiend in Chook::Subject.classes

# File lib/chook/subject/test_subject.rb, line 172
def initialize(subject_data = nil)
  classname = self.class.const_get Chook::Subject::NAME_CONSTANT
  attribs = Chook::Subject.classes[classname]

  if subject_data
    subject_data.each do |key, value|
      # ignore unknown attributes. Shouldn't get any, but...
      next unless attribs[key]

      # does the value need conversion?
      converter = attribs[key][:converter]
      if converter
        value = converter.is_a?(Symbol) ? value.send(converter) : converter.call(value)
      end # if converter
      instance_variable_set(('@' + key.to_s), value)
    end # each key value
  else
    attribs.keys.each { |key| instance_variable_set(('@' + key.to_s), nil) }
  end # if subject_data
end
random() click to toggle source

a random test subject,

# File lib/chook/subject/test_subject.rb, line 73
def self.random
  random_vals = {}
  Chook::Subject.classes[self.const_get NAME_CONSTANT].each do |attrib, deets|
    random_vals[attrib] = Chook::Randomizers.send deets[:randomizer] if deets[:randomizer]
  end # each do |attr_def|
  new random_vals
end
sample(ids = 'random', api: JSS.api) click to toggle source

a sampled test subject (real data from real JSS objects) NOTE: a valid ruby-jss JSS::APIConnection must exist

# File lib/chook/subject/test_subject.rb, line 83
def self.sample(ids = 'random', api: JSS.api)
  classname = self.const_get Chook::Subject::NAME_CONSTANT
  ids = [ids] if ids.is_a? Integer
  # !!Kernel.const_get('JSS::' + classname) rescue false
  if classname == 'PatchSoftwareTitleUpdated'
    all_ids = Chook::Samplers.all_patch_ids('blah', api: api)
  else
    all_ids = Kernel.const_get('JSS::' + classname).all_ids(api: api) # (api: api)
  end
  ids = [all_ids.sample] if ids == 'random'

  ok = true
  if ids.is_a? Array
    ids.each { |id| ok == false unless id.is_a? Integer }
  else
    ok = false
  end
  raise 'ids must be an Array of Integers' unless ok

  raw_samples = []
  samples = []

  valid_ids = ids & all_ids
  raise "Invalid JSS IDs: #{ids}" if valid_ids.empty?

  valid_ids.each do |id|
    if classname == 'PatchSoftwareTitleUpdated'
      raw_samples << Chook::Samplers.all_patches(api: api).select { |patch| patch[:id] == id }
      raw_samples.flatten!
    else
      raw_samples << Kernel.const_get('JSS::' + classname).fetch(id: id, api: api)
    end
  end

  raw_samples.each do |sample|
    subject_details = {}
    Chook::Subject.classes[classname].map do |subject_key, details|
      extractor = details[:api_object_attribute]
      subject_details[subject_key] =
        case extractor
        when Symbol
          if classname == 'PatchSoftwareTitleUpdated'
            # If there is a sampler method available, call it.
            if details[:sampler]
              extractor = details[:sampler]
              Chook::Samplers.send(extractor, sample)
            else
              # Otherwise use it like a hash key
              sample[extractor]
            end
          else
            sample.send extractor
          end
        when Array
          extractor = extractor.dup # If this doesn't get duplicated, shift will change details[:api_object_attribute]
          method = extractor.shift
          raw_hash_keys = extractor
          method_result = sample.send(method)
          raw_hash_keys.each { |key| method_result = method_result[key] }
          method_result
        when Proc
          extractor.call sample
        end
    end # do |subject_key, details|
    samples << Kernel.const_get('Chook::TestSubjects::' + classname).new(subject_details)
  end # end samples.each do |sample|
  samples
end

Public Instance Methods

json_hash() click to toggle source
# File lib/chook/subject/test_subject.rb, line 152
def json_hash
  # Verify that input is a child of TestSubjects, raise if not
  raise 'Invalid TestSubject' unless self.class.superclass == Chook::TestSubject
  test_subject_attributes = Chook::Subject.classes[self.class.to_s.split('::')[-1]]
  raw_hash_form = {}
  test_subject_attributes.each do |attribute, details|
    if details.keys.include? :to_json
      raw_hash_form[attribute] = send(attribute).send details[:to_json]
    else
      raw_hash_form[attribute] = instance_variable_get('@' + attribute.to_s)
    end
  end # end test_subject_attributes.keys.each do |attribute, details|
  raw_hash_form
end