Skip to content

Commit

Permalink
v0.4 - Patch event
Browse files Browse the repository at this point in the history
Added Patch object for patch title events. Updated docs and tests.
  • Loading branch information
brysontyrrell committed Jun 5, 2017
1 parent 5b7281e commit 6b8a941
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 29 deletions.
4 changes: 4 additions & 0 deletions docs/events/patch.rst
@@ -0,0 +1,4 @@
Patch Title Events
------------------

.. autoclass:: jook.models.webhooks.PatchTitle
1 change: 1 addition & 0 deletions docs/index.rst
Expand Up @@ -15,3 +15,4 @@ Welcome to Jook's documentation!
events/base
events/devices
events/jamfpro
events/patch
4 changes: 2 additions & 2 deletions jook/__init__.py
@@ -1,9 +1,9 @@
"""Jook: A Jamf Pro webhook simulator"""
from .models.webhooks import Computer, MobileDevice, JamfPro
from .models.webhooks import Computer, MobileDevice, JamfPro, PatchTitle
from .models.data_sets import DeviceData, LocationData


__title__ = 'jook'
__version__ = '0.3'
__version__ = '0.4'
__author__ = 'Bryson Tyrrell'
__copyright__ = '(c) 2017 Bryson Tyrrell'
86 changes: 80 additions & 6 deletions jook/models/webhooks.py
@@ -1,7 +1,7 @@
"""
This module contains the main classes that will be interacted with directly.
"""

import datetime
import json
import time
from urlparse import urlparse
Expand Down Expand Up @@ -90,14 +90,27 @@ def __init__(self, url, event, webhook_id=1, webhook_name='Webhook',

self.timer = int(timer)

self._webhook_data = {
"webhook": {
"id": self.id,
"name": self.name,
"webhookEvent": self.event
}
}

@property
def data(self):
"""This method generates the object data in JSON or XML format which is
set by the ``data_type`` attributes.
This method should be overridden by children that inherit this object.
The ``data`` object contains the event specific key-values. It is then
updated with the key-values from ``_base_data``.
"""
return {}
data = {"event": {}}
data.update(self._webhook_data)
return data

def to_json(self):
"""
Expand Down Expand Up @@ -284,14 +297,14 @@ def __init__(self, *args, **kwargs):
:param str institution: The name of the organization the server is
registered to (defaults to 'Example Org').
:param str host_address: The IP address of the originating server (defaults
to ``10.0.0.1``).
:param str host_address: The IP address of the originating server
(defaults to ``10.0.0.1``).
:param str web_app_path: The root path of the web app for the server
(defaults to ``/``).
:param bool is_master: Is the originating server a cluster master (defaults
to ``True``).
:param bool is_master: Is the originating server a cluster master
(defaults to ``True``).
:param str server_url: The URL of the originating server (defaults to
``https://jss.example.org``).
Expand Down Expand Up @@ -325,3 +338,64 @@ def data(self):
"jssUrl": self.server_url
}
}


class PatchTitle(BaseWebhook):
"""The base webhook object for 'Patch Title' events."""
valid_events = ('PatchSoftwareTitleUpdated',)

def __init__(self, *args, **kwargs):
"""
:param int jss_id: ID of the Patch Title in Jamf Pro (defaults to 1).
:param str patch_name: The Patch Title name (defaults to 'Flash').
:param str patch_version: The new Patch Title version (defaults to 1).
:param str report_url: The URL to the Patch Title's report in Jamr Pro
(Defaults to 'https://jss.example.org/patch.html?id=' + the JSS ID).
:param int timestamp: The UNIX timestamp of when the Patch Title was
updated. If not provided, or not a valid timestamp, it will be
set to the current time.
"""
super(PatchTitle, self).__init__(
event='PatchSoftwareTitleUpdated', *args, **kwargs)

self.jss_id = kwargs.pop('jss_id', 1)
self.patch_name = kwargs.pop('patch_name', 'Flash')
self.patch_version = kwargs.pop('patch_version', '1')
self.patch_report_url = kwargs.pop(
'report_url',
'https://jss.example.org/patch.html?id={}'.format(self.jss_id)
)
self.patch_timestamp = kwargs.pop('timestamp', None)

try:
datetime.datetime.fromtimestamp(self.patch_timestamp)
except TypeError:
self.patch_timestamp = int(time.time() * 1000)

@property
def data(self):
"""Return ``data`` for the object as a dictionary.
:return: ``data`` as a dictionary object
:rtype: dict
"""
data = {
"event": {
"name": self.patch_name,
"latestVersion": self.patch_version,
"lastUpdate": self.patch_timestamp,
"reportUrl": self.patch_report_url,
"jssID": self.jss_id
}
}
data.update(self._webhook_data)
return data


class SmartGroup(BaseWebhook):
pass
65 changes: 44 additions & 21 deletions tests/test_jook.py
Expand Up @@ -5,6 +5,7 @@
import responses

import jook
from jook.models.webhooks import BaseWebhook
from jook.exceptions import InvalidEvent, InvalidURL


Expand All @@ -13,48 +14,70 @@

def test_url_scheme_required():
with pytest.raises(InvalidURL):
jook.Computer('localhost', 'ComputerAdded')
BaseWebhook('localhost', '')


def test_valid_events():
for event in jook.Computer.valid_events:
jook.Computer(URL, event)
def test_events():
events = (
jook.Computer,
jook.MobileDevice,
jook.JamfPro
)

for event in events:
for valid_event in event.valid_events:
assert event(URL, valid_event)

for event in jook.MobileDevice.valid_events:
jook.MobileDevice(URL, event)
with pytest.raises(InvalidEvent):
event(URL, 'InvalidEvent')

for event in jook.JamfPro.valid_events:
jook.JamfPro(URL, event)

with pytest.raises(InvalidEvent):
jook.Computer(URL, 'SomeEvent')
jook.MobileDevice(URL, 'SomeEvent')
jook.JamfPro(URL, 'SomeEvent')
def test_event_required():
events = (
jook.Computer,
jook.MobileDevice,
jook.JamfPro
)

with pytest.raises(TypeError):
for event in events:
event(URL)


def test_event_not_required():
events = (
jook.PatchTitle,
)

for event in events:
assert event(URL)


def test_static_data():
def test_static_device_data():
computer = jook.Computer(URL, 'ComputerAdded')
assert computer.data == computer.data

mobile = jook.MobileDevice(URL, 'MobileDeviceCheckIn')
assert mobile.data == mobile.data


def test_random_data():
computer = jook.Computer(URL, 'ComputerAdded', randomize=True)
def test_random_device_data():
computer = jook.Computer(URL, 'ComputerCheckIn', randomize=True)
assert computer.data != computer.data

mobile = jook.MobileDevice(URL, 'MobileDeviceCheckIn', randomize=True)
mobile = jook.MobileDevice(
URL, 'MobileDeviceCommandCompleted', randomize=True)
assert mobile.data != mobile.data


def test_data_modes():
events = (
jook.Computer(URL, 'ComputerAdded'),
jook.MobileDevice(URL, 'MobileDeviceCheckIn'),
jook.JamfPro(URL, 'JSSShutdown')
jook.Computer(URL, 'ComputerInventoryCompleted'),
jook.MobileDevice(URL, 'MobileDeviceEnrolled'),
jook.JamfPro(URL, 'JSSShutdown'),
jook.PatchTitle(URL)
)

for event in events:
json.loads(event.to_json())
Et.fromstring(event.to_xml())
assert json.loads(event.to_json())
assert Et.fromstring(event.to_xml())

0 comments on commit 6b8a941

Please sign in to comment.