Class: Chook::TestSubject

Inherits:
Subject
  • Object
show all
Defined in:
lib/chook/subject/test_subject.rb

Overview

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.

Constant Summary

Constants inherited from Subject

Subject::COMPUTER, Subject::JAMF_SOFTWARE_SERVER, Subject::MOBILE_DEVICE, Subject::NAME_CONSTANT, Subject::PATCH_SW_UPDATE, Subject::PUSH, Subject::REST_API_OPERATION, Subject::SCEP_CHALLENGE, Subject::SMART_GROUP

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Subject

classes

Constructor Details

#initialize(subject_data = nil) ⇒ TestSubject

All the subclassses will inherit this constructor

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


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# 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

Class Method Details

.generate_classesObject

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


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 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

.randomObject

a random test subject,


73
74
75
76
77
78
79
# 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) ⇒ Object

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


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# 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

Instance Method Details

#json_hashObject

end sample


152
153
154
155
156
157
158
159
160
161
162
163
164
165
# 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