Beispiel #1
0
 def test_to_dict(self):
     instance = Condition(WeatherParametersEnum.TEMPERATURE, OperatorsEnum.GREATER_THAN, 78.6, id='123456')
     result = instance.to_dict()
     self.assertIsInstance(result, dict)
     self.assertEqual('123456', result['id'])
     self.assertEqual(WeatherParametersEnum.TEMPERATURE, result['weather_param'])
     self.assertEqual(OperatorsEnum.GREATER_THAN, result['operator'])
     self.assertEqual(78.6, result['amount'])
Beispiel #2
0
 def test_from_dict(self):
     expected = Condition(WeatherParametersEnum.TEMPERATURE,
                          OperatorsEnum.GREATER_THAN,
                          78.6,
                          id='123456')
     the_dict = dict(name='temp',
                     expression='$gt',
                     amount=78.6,
                     _id='123456')
     result = Condition.from_dict(the_dict)
     self.assertEqual(expected.weather_param, result.weather_param)
     self.assertEqual(expected.operator, result.operator)
     self.assertEqual(expected.amount, result.amount)
     self.assertEqual(expected.id, result.id)
Beispiel #3
0
    def test_get_alerts_on(self):
        cond1 = Condition('humidity', 'LESS_THAN', 10)
        cond2 = Condition('temp', 'GREATER_THAN_EQUAL', 100.6)
        alert1 = Alert('alert1', 'trigger1', [{
            "current_value": 8.576,
            "condition": cond1
        }], {
            "lon": 37,
            "lat": 53
        }, 1000)
        alert2 = Alert('alert2', 'trigger1', [{
            "current_value": 111.576,
            "condition": cond2
        }], {
            "lon": 37,
            "lat": 53
        }, 3000)
        alert3 = Alert('alert3', 'trigger1', [{
            "current_value": 119.332,
            "condition": cond2
        }], {
            "lon": 37,
            "lat": 53
        }, 9000)
        alert4 = Alert('alert4', 'trigger1', [{
            "current_value": 7.332,
            "condition": cond1
        }], {
            "lon": 37,
            "lat": 53
        }, 12000)
        alerts = [alert1, alert2, alert3, alert4]
        instance = Trigger(1526809375,
                           1527809375, [cond1, cond2], [geo.Point(13.6, 46.9)],
                           alerts=alerts,
                           alert_channels=None)
        result = instance.get_alerts_on('temp')
        self.assertEqual(2, len(result))
        self.assertTrue(alert2 in result)
        self.assertTrue(alert3 in result)

        result = instance.get_alerts_on('humidity')
        self.assertEqual(2, len(result))
        self.assertTrue(alert1 in result)
        self.assertTrue(alert4 in result)

        result = instance.get_alerts_on('wind_direction')
        self.assertEqual(0, len(result))
    def parse_JSON(self, JSON_string):
        """
        Parses a `pyowm.alertapi30.alert.Alert` instance out of raw JSON data.

        :param JSON_string: a raw JSON string
        :type JSON_string: str
        :return: a `pyowm.alertapi30.alert.Alert` instance or ``None``
            if no data is available
        :raises: *ParseResponseError* if it is impossible to find or parse the
            data needed to build the result

        """
        if JSON_string is None:
            raise parse_response_error.ParseResponseError('JSON data is None')
        d = json.loads(JSON_string)
        try:
            alert_id = d['_id']
            t = d['last_update'].split('.')[0].replace('T', ' ') + '+00'
            alert_last_update = timeformatutils._ISO8601_to_UNIXtime(t)
            alert_trigger_id = d['triggerId']
            alert_met_conds = [
                dict(current_value=c['current_value']['min'], condition=Condition.from_dict(c['condition']))
                    for c in d['conditions']
            ]
            alert_coords = d['coordinates']
            return Alert(alert_id, alert_trigger_id, alert_met_conds, alert_coords, last_update=alert_last_update)

        except ValueError as e:
            raise parse_response_error.ParseResponseError('Impossible to parse JSON: %s' % e)
        except KeyError as e:
            raise parse_response_error.ParseResponseError('Impossible to parse JSON: %s' % e)
 def test_to_dict(self):
     condition = Condition('humidity', 'LESS_THAN', 10)
     instance = Alert('alert1', 'trigger1', [{
         "current_value": 263.576,
         "condition": condition.to_dict()}],
         {"lon": 37, "lat": 53},
         1481802090232)
     result = instance.to_dict()
     self.assertIsInstance(result, dict)
     self.assertEqual('alert1', result['id'])
     self.assertEqual('trigger1', result['trigger_id'])
     self.assertEqual(1, len(result['met_conditions']))
     mc = result['met_conditions'][0]
     self.assertEqual(dict(current_value=263.576, condition=condition.to_dict()), mc)
     self.assertEqual({"lon": 37, "lat": 53}, result['coordinates'])
     self.assertEqual(1481802090232, result['last_update'])
Beispiel #6
0
    def from_dict(cls, the_dict):
        """
        Parses a *Alert* instance out of a data dictionary. Only certain properties of the data dictionary
        are used: if these properties are not found or cannot be parsed, an exception is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: a *Alert* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the data needed to build the result

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        try:
            alert_id = the_dict['_id']
            t = the_dict['last_update'].split('.')[0].replace('T', ' ') + '+00'
            alert_last_update = formatting.ISO8601_to_UNIXtime(t)
            alert_trigger_id = the_dict['triggerId']
            alert_met_conds = [
                dict(current_value=c['current_value']['min'],
                     condition=Condition.from_dict(c['condition']))
                for c in the_dict['conditions']
            ]
            alert_coords = the_dict['coordinates']
            return Alert(alert_id,
                         alert_trigger_id,
                         alert_met_conds,
                         alert_coords,
                         last_update=alert_last_update)
        except ValueError as e:
            raise exceptions.ParseAPIResponseError(
                'Impossible to parse JSON: %s' % e)
        except KeyError as e:
            raise exceptions.ParseAPIResponseError(
                'Impossible to parse JSON: %s' % e)
 def test_to_dict(self):
     cond = Condition('humidity', 'LESS_THAN', 10)
     instance = Trigger(1526809375,
                        1527809375, [cond], [geo.Point(13.6, 46.9)],
                        alerts=[],
                        alert_channels=None,
                        id='myid')
     result = instance.to_dict()
     self.assertIsInstance(result, dict)
     self.assertEqual('myid', result['id'])
     self.assertEqual(1526809375, result['start_after_millis'])
     self.assertEqual(1527809375, result['end_after_millis'])
     self.assertEqual([dict(name='OWM API POLLING')],
                      result['alert_channels'])
     self.assertEqual(list(), result['alerts'])
     self.assertEqual([{
         'type': 'Point',
         'coordinates': [13.6, 46.9]
     }], result['area'])
     self.assertEqual([{
         'id': None,
         'weather_param': 'humidity',
         'operator': 'LESS_THAN',
         'amount': 10
     }], result['conditions'])
Beispiel #8
0
 def test_get_alerts(self):
     cond = Condition('humidity', 'LESS_THAN', 10)
     alert1 = Alert('alert1', 'trigger1', [{
         "current_value": 263.576,
         "condition": cond
     }], {
         "lon": 37,
         "lat": 53
     }, 1481802090232)
     alert2 = Alert('alert2', 'trigger1', [{
         "current_value": 111.576,
         "condition": cond
     }], {
         "lon": 37,
         "lat": 53
     }, 1481802100000)
     alerts = [alert1, alert2]
     instance = Trigger(1526809375,
                        1527809375, [cond], [geo.Point(13.6, 46.9)],
                        alerts=alerts,
                        alert_channels=None)
     result = instance.get_alerts()
     self.assertTrue(isinstance(result, list))
     self.assertTrue(alert1 in result)
     self.assertTrue(alert2 in result)
 def test_repr(self):
     instance = Trigger(1526809375,
                        1527809375,
                        [Condition('humidity', 'LESS_THAN', 10)],
                        [geo.Point(13.6, 46.9)],
                        alerts=None,
                        alert_channels=None)
     print(instance)
Beispiel #10
0
 def test_from_dict(self):
     expected = Condition(WeatherParametersEnum.TEMPERATURE, OperatorsEnum.GREATER_THAN, 78.6, id='123456')
     the_dict = dict(name='temp', expression='$gt',
                     amount=78.6, _id='123456')
     result = Condition.from_dict(the_dict)
     self.assertEqual(expected.weather_param, result.weather_param)
     self.assertEqual(expected.operator, result.operator)
     self.assertEqual(expected.amount, result.amount)
     self.assertEqual(expected.id, result.id)
 def test_init(self):
     alert_channels = [AlertChannelsEnum.items()]
     instance = Trigger(1526809375,
                        1527809375,
                        [Condition('humidity', 'LESS_THAN', 10)],
                        [geo.Point(13.6, 46.9)],
                        alerts=None,
                        alert_channels=alert_channels)
     self.assertEqual(instance.alert_channels, alert_channels)
Beispiel #12
0
 def test_defaulted_parameters(self):
     instance = Trigger(1526809375,
                        1527809375,
                        [Condition('humidity', 'LESS_THAN', 10)],
                        [geo.Point(13.6, 46.9)],
                        alerts=None,
                        alert_channels=None)
     self.assertIsInstance(instance.alerts, list)
     self.assertEqual(0, len(instance.alerts))
     self.assertIsInstance(instance.alert_channels, list)
     self.assertEqual(1, len(instance.alert_channels))
     self.assertEqual(instance.alert_channels[0],
                      AlertChannelsEnum.OWM_API_POLLING)
Beispiel #13
0
def weather_alerts(owm_api, lat, lng):
    owm_obj = OWM(owm_api)
    am = owm_obj.alert_manager()

    # available types: Point, MultiPoint, Polygon, MultiPolygon
    geom_1 = geo.Point(lng, lat)

    # TBD: Alert should be cast over a wide area.
    # Alerts will have far reaching effects.
    #geom_1.geojson()
    #'''
    #{
    #  "type": "Point",
    #  "coordinates":[ lon, lat ]
    #}
    #'''
    # Pune - Mumbai - Satara - Pune
    # Indore - Nagpur - Hyderabad - Indore
    #geom_2 = geo.MultiPolygon([[73.856743, 18.520430], [72.877655, 19.075983]])

    # -- conditions --
    condition_1 = Condition(WeatherParametersEnum.TEMPERATURE,
                        OperatorsEnum.GREATER_THAN,
                        310.15)  # kelvin, 35C
    condition_2 = Condition(WeatherParametersEnum.CLOUDS,
                        OperatorsEnum.GREATER_THAN,
                        60) # clouds % coverage

    # create a trigger
    trigger = am.create_trigger(start_after_millis=355000, end_after_millis=487000,\
                            conditions=[condition_1, condition_2],\
                            area=[geom_1],\
                            alert_channel=AlertChannelsEnum.OWM_API_POLLING)

    # read all triggers
    triggers_list = am.get_triggers()
    print("Read all Weather triggers: {}".format(triggers_list))
Beispiel #14
0
    def test_get_alerts_since(self):
        cond = Condition('humidity', 'LESS_THAN', 10)
        alert1 = Alert('alert1', 'trigger1', [{
            "current_value": 263.576,
            "condition": cond
        }], {
            "lon": 37,
            "lat": 53
        }, 1000)
        alert2 = Alert('alert2', 'trigger1', [{
            "current_value": 111.576,
            "condition": cond
        }], {
            "lon": 37,
            "lat": 53
        }, 3000)
        alert3 = Alert('alert3', 'trigger1', [{
            "current_value": 119.332,
            "condition": cond
        }], {
            "lon": 37,
            "lat": 53
        }, 9000)
        alert4 = Alert('alert4', 'trigger1', [{
            "current_value": 119.332,
            "condition": cond
        }], {
            "lon": 37,
            "lat": 53
        }, 12000)
        alerts = [alert1, alert2, alert3, alert4]
        instance = Trigger(1526809375,
                           1527809375, [cond], [geo.Point(13.6, 46.9)],
                           alerts=alerts,
                           alert_channels=None)

        result = instance.get_alerts_since(4000)
        self.assertEqual(2, len(result))
        self.assertTrue(alert3 in result)
        self.assertTrue(alert4 in result)

        result = instance.get_alerts_since(3000)
        self.assertEqual(3, len(result))
        self.assertTrue(alert2 in result)
        self.assertTrue(alert3 in result)
        self.assertTrue(alert4 in result)

        result = instance.get_alerts_since(15000)
        self.assertEqual(0, len(result))
Beispiel #15
0
 def test_get_alert(self):
     cond = Condition('humidity', 'LESS_THAN', 10)
     alert = Alert('alert1', 'trigger1', [{
         "current_value": 263.576,
         "condition": cond
     }], {
         "lon": 37,
         "lat": 53
     }, 1481802090232)
     alerts = [alert]
     instance = Trigger(1526809375,
                        1527809375, [cond], [geo.Point(13.6, 46.9)],
                        alerts=alerts,
                        alert_channels=None)
     self.assertEqual(alert, instance.get_alert('alert1'))
Beispiel #16
0
    def test_from_dict(self):
        expected = Condition(WeatherParametersEnum.TEMPERATURE, OperatorsEnum.GREATER_THAN, 78.6, id='123456')
        the_dict = dict(name='temp', expression='$gt',
                        amount=78.6, _id='123456')
        result = Condition.from_dict(the_dict)
        self.assertEqual(expected.weather_param, result.weather_param)
        self.assertEqual(expected.operator, result.operator)
        self.assertEqual(expected.amount, result.amount)
        self.assertEqual(expected.id, result.id)

        with self.assertRaises(pyowm.commons.exceptions.ParseAPIResponseError):
            Condition.from_dict(None)

        with self.assertRaises(pyowm.commons.exceptions.ParseAPIResponseError):
            Condition.from_dict(dict(nonexistent='key'))
    def test_get_alert(self):
        cond = Condition('humidity', 'LESS_THAN', 10)
        alert = Alert('alert1', 'trigger1', [{
            "current_value": 263.576,
            "condition": cond
        }], {
            "lon": 37,
            "lat": 53
        }, 1481802090232)
        alert_two = copy.deepcopy(alert)
        alert_two.id = 'alert_two'
        alerts = [alert_two, alert
                  ]  # Second alert has to be 1st element to have full coverage
        instance = Trigger(1526809375,
                           1527809375, [cond], [geo.Point(13.6, 46.9)],
                           alerts=alerts,
                           alert_channels=None)
        self.assertEqual(alert, instance.get_alert('alert1'))

        # Trigger without alerts
        instance.alerts = []
        self.assertIsNone(instance.get_alert(alert_id='alert1'))
Beispiel #18
0
 def test_repr(self):
     print(Condition(WeatherParametersEnum.TEMPERATURE, OperatorsEnum.GREATER_THAN, 78.6, id='123456'))
 def test_alert_last_updated_is_none(self):
     alert = Alert('alert1', 'trigger1', [{
         "current_value": 263.576,
         "condition": Condition('humidity', 'LESS_THAN', 10)}],
                   {"lon": 37, "lat": 53})
     self.assertIsNone(alert.last_update)
class IntegrationTestsAlertAPI30(unittest.TestCase):

    __owm = OWM25(parsers, os.getenv('OWM_API_KEY', DEFAULT_API_KEY))

    cond1 = Condition(WeatherParametersEnum.HUMIDITY, OperatorsEnum.LESS_THAN,
                      10)
    cond2 = Condition(WeatherParametersEnum.CLOUDS, OperatorsEnum.LESS_THAN,
                      90)
    start = '2019-07-01 14:17:00+00'
    end = '2019-07-02 14:17:00+00'
    # a rectangle around the city of Moscow
    area1 = geo.Polygon.from_dict({
        "type":
        "Polygon",
        "coordinates": [[[36.826171875, 55.17259379606185],
                         [39.012451171875, 55.17259379606185],
                         [39.012451171875, 56.15778819063682],
                         [36.826171875, 56.15778819063682],
                         [36.826171875, 55.17259379606185]]]
    })
    # somewhere in Dubai

    area2 = geo.Point.from_dict({
        "type":
        "Point",
        "coordinates": [55.29693603515625, 25.186301620540558]
    })

    def test_triggers_CRUD(self):

        mgr = self.__owm.alert_manager()

        # check if any previous triggers exist on this account
        n_old_triggers = len(mgr.get_triggers())

        # create trigger1
        trigger1 = mgr.create_trigger(self.start,
                                      self.end,
                                      conditions=[self.cond1],
                                      area=[self.area1])

        # create trigger2
        trigger2 = mgr.create_trigger(self.start,
                                      self.end,
                                      conditions=[self.cond2],
                                      area=[self.area2])

        # Read all created triggers
        triggers = mgr.get_triggers()
        self.assertEqual(n_old_triggers + 2, len(triggers))

        # Read one by one
        result = mgr.get_trigger(trigger1.id)
        self.assertEqual(trigger1.id, result.id)
        self.assertEqual(trigger1.start_after_millis,
                         result.start_after_millis)
        self.assertEqual(trigger1.end_after_millis, result.end_after_millis)
        self.assertEqual(len(trigger1.conditions), len(result.conditions))
        self.assertEqual(len(trigger1.area), len(result.area))

        result = mgr.get_trigger(trigger2.id)
        self.assertEqual(trigger2.id, result.id)
        self.assertEqual(trigger2.start_after_millis,
                         result.start_after_millis)
        self.assertEqual(trigger2.end_after_millis, result.end_after_millis)
        self.assertEqual(len(trigger2.conditions), len(result.conditions))
        self.assertEqual(len(trigger2.area), len(result.area))

        # Update a trigger
        modified_trigger2 = copy.deepcopy(trigger2)
        modified_trigger2.conditions = [self.cond1, self.cond2]

        mgr.update_trigger(modified_trigger2)
        result = mgr.get_trigger(modified_trigger2.id)

        self.assertEqual(modified_trigger2.id, result.id)
        self.assertEqual(modified_trigger2.start_after_millis,
                         result.start_after_millis)
        self.assertEqual(modified_trigger2.end_after_millis,
                         result.end_after_millis)
        self.assertEqual(len(modified_trigger2.area), len(result.area))
        # of course, conditions have been modified with respect to former trigger 2
        self.assertNotEqual(len(trigger2.conditions), len(result.conditions))
        self.assertEqual(len(modified_trigger2.conditions),
                         len(result.conditions))

        # Delete triggers one by one
        mgr.delete_trigger(trigger1)
        triggers = mgr.get_triggers()
        self.assertEqual(n_old_triggers + 1, len(triggers))

        mgr.delete_trigger(modified_trigger2)
        triggers = mgr.get_triggers()
        self.assertEqual(n_old_triggers, len(triggers))
Beispiel #21
0
    def from_dict(cls, the_dict):
        if the_dict is None:
            raise pyowm.commons.exceptions.ParseAPIResponseError(
                'Data is None')
        try:
            # trigger id
            trigger_id = the_dict.get('_id', None)

            # start timestamp
            start_dict = the_dict['time_period']['start']
            expr = start_dict['expression']
            if expr != 'after':
                raise ValueError(
                    'Invalid time expression: "%s" on start timestamp. Only: "after" is supported'
                    % expr)
            start = start_dict['amount']

            # end timestamp
            end_dict = the_dict['time_period']['end']
            expr = end_dict['expression']
            if expr != 'after':
                raise ValueError(
                    'Invalid time expression: "%s" on end timestamp. Only: "after" is supported'
                    % expr)
            end = end_dict['amount']

            # conditions
            conditions = [
                Condition.from_dict(c) for c in the_dict['conditions']
            ]

            # alerts
            alerts_dict = the_dict['alerts']
            alerts = list()
            for key in alerts_dict:
                alert_id = key
                alert_data = alerts_dict[alert_id]
                alert_last_update = alert_data['last_update']
                alert_met_conds = []
                for c in alert_data['conditions']:
                    if isinstance(c['current_value'], int):
                        cv = c['current_value']
                    else:
                        cv = c['current_value']['min']
                    item = dict(current_value=cv,
                                condition=Condition.from_dict(c['condition']))
                    alert_met_conds.append(item)
                alert_coords = alert_data['coordinates']
                alert = Alert(alert_id,
                              trigger_id,
                              alert_met_conds,
                              alert_coords,
                              last_update=alert_last_update)
                alerts.append(alert)

            # area
            area_list = the_dict['area']
            area = [GeometryBuilder.build(a_dict) for a_dict in area_list]

            # alert channels
            alert_channels = None  # defaulting

        except ValueError as e:
            raise pyowm.commons.exceptions.ParseAPIResponseError(
                'Impossible to parse JSON: %s' % e)

        except KeyError as e:
            raise pyowm.commons.exceptions.ParseAPIResponseError(
                'Impossible to parse JSON: %s' % e)

        return Trigger(start,
                       end,
                       conditions,
                       area=area,
                       alerts=alerts,
                       alert_channels=alert_channels,
                       id=trigger_id)
Beispiel #22
0
    def test_trigger_fails_with_wrong_parameters(self):
        start_after_millis = 450000
        end_after_millis = 470000
        conditions = [Condition('humidity', 'LESS_THAN', 10)]
        area = [geo.Point(13.6, 46.9)]

        self.assertRaises(AssertionError,
                          Trigger,
                          None,
                          end_after_millis,
                          conditions,
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)
        self.assertRaises(AssertionError,
                          Trigger,
                          start_after_millis,
                          None,
                          conditions,
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)
        self.assertRaises(AssertionError,
                          Trigger,
                          'test',
                          end_after_millis,
                          conditions,
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)
        self.assertRaises(AssertionError,
                          Trigger,
                          start_after_millis,
                          'test',
                          conditions,
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)
        self.assertRaises(ValueError,
                          Trigger,
                          end_after_millis,
                          start_after_millis,
                          conditions,
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)

        self.assertRaises(AssertionError,
                          Trigger,
                          start_after_millis,
                          end_after_millis,
                          None,
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)
        self.assertRaises(ValueError,
                          Trigger,
                          start_after_millis,
                          end_after_millis, [],
                          area,
                          alerts=None,
                          alert_channels=None,
                          id=None)

        self.assertRaises(AssertionError,
                          Trigger,
                          start_after_millis,
                          end_after_millis,
                          conditions,
                          None,
                          alerts=None,
                          alert_channels=None,
                          id=None)
        self.assertRaises(ValueError,
                          Trigger,
                          start_after_millis,
                          end_after_millis,
                          conditions, [],
                          alerts=None,
                          alert_channels=None,
                          id=None)

        _ = Trigger(start_after_millis,
                    end_after_millis,
                    conditions,
                    area,
                    alerts=None,
                    alert_channels=None)
Beispiel #23
0
class TestAlertManager(unittest.TestCase):
    _cond1 = Condition('humidity', 'LESS_THAN', 10)
    _cond2 = Condition('temp', 'GREATER_THAN_EQUAL', 100.6)
    _trigger = Trigger(1526809375,
                       1527809375, [_cond1, _cond2], [geo.Point(13.6, 46.9)],
                       alerts=[],
                       alert_channels=None,
                       id='trigger-id')
    _alert = Alert('alert1', 'trigger1', [{
        "current_value": 263.576,
        "condition": _cond1
    }], {
        "lon": 37,
        "lat": 53
    }, 1481802090232)

    def factory(self, _kls):
        sm = AlertManager('APIKey')
        sm.http_client = _kls()
        return sm

    def test_instantiation_fails_without_api_key(self):
        self.assertRaises(AssertionError, AlertManager, None)

    def test_get_alert_api_version(self):
        instance = AlertManager('APIKey')
        result = instance.alert_api_version()
        self.assertIsInstance(result, tuple)
        self.assertEqual(result, ALERT_API_VERSION)

    def test_get_triggers(self):
        instance = self.factory(MockHttpClientTwoTriggers)
        results = instance.get_triggers()
        self.assertEqual(2, len(results))
        t = results[0]
        self.assertIsInstance(t, Trigger)

    def test_get_trigger_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.get_trigger(None)
        with self.assertRaises(AssertionError):
            instance.get_trigger(123)

    def test_get_trigger(self):
        instance = self.factory(MockHttpClientOneTrigger)
        result = instance.get_trigger('any-id')
        self.assertIsInstance(result, Trigger)

    def test_create_trigger(self):
        instance = self.factory(MockHttpClient)
        result = instance.create_trigger(1526809375,
                                         1527809375,
                                         [self._cond1, self._cond2],
                                         [geo.Point(13.6, 46.9)],
                                         alert_channels=None)
        self.assertIsInstance(result, Trigger)

    def test_create_trigger_fails_with_wrong_inputs(self):
        instance = self.factory(MockHttpClient)
        with self.assertRaises(AssertionError):
            instance.create_trigger(None,
                                    1527809375, [self._cond1, self._cond2],
                                    [geo.Point(13.6, 46.9)],
                                    alert_channels=None)
        with self.assertRaises(AssertionError):
            instance.create_trigger(1526809375,
                                    None, [self._cond1, self._cond2],
                                    [geo.Point(13.6, 46.9)],
                                    alert_channels=None)
        with self.assertRaises(ValueError):
            instance.create_trigger(1526809375,
                                    1327809375, [self._cond1, self._cond2],
                                    [geo.Point(13.6, 46.9)],
                                    alert_channels=None)
        with self.assertRaises(AssertionError):
            instance.create_trigger(1526809375,
                                    1527809375,
                                    None, [geo.Point(13.6, 46.9)],
                                    alert_channels=None)
        with self.assertRaises(ValueError):
            instance.create_trigger(1526809375,
                                    1527809375, [], [geo.Point(13.6, 46.9)],
                                    alert_channels=None)
        with self.assertRaises(AssertionError):
            instance.create_trigger(1526809375,
                                    1527809375, [self._cond1, self._cond2],
                                    None,
                                    alert_channels=None)
        with self.assertRaises(ValueError):
            instance.create_trigger(1526809375,
                                    1527809375, [self._cond1, self._cond2], [],
                                    alert_channels=None)

    def test_delete_trigger_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.delete_trigger(None)
        with self.assertRaises(AssertionError):
            self._trigger.id = 123
            instance.delete_trigger(self._trigger)

    def test_delete_trigger(self):
        instance = self.factory(MockHttpClient)
        parser = TriggerParser()
        trigger = parser.parse_JSON(MockHttpClient.test_trigger_json)
        result = instance.delete_trigger(trigger)
        self.assertIsNone(result)

    def test_update_trigger_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.update_trigger(None)
        with self.assertRaises(AssertionError):
            self._trigger.id = 123
            instance.update_trigger(self._trigger)

    def test_update_trigger(self):
        instance = self.factory(MockHttpClient)
        parser = TriggerParser()
        modified_trigger = parser.parse_JSON(MockHttpClient.test_trigger_json)
        modified_trigger.id = '5852816a9aaacb00153134a3'
        modified_trigger.end = self._trigger.end_after_millis + 10000
        result = instance.update_trigger(modified_trigger)
        self.assertIsNone(result)

    def test_get_alerts_for_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.get_alerts_for(None)
        with self.assertRaises(AssertionError):
            self._trigger.id = 123
            instance.get_alerts_for(self._trigger)

    def test_get_alerts_for(self):
        instance = self.factory(MockHttpClientTwoAlerts)
        self._trigger.id = 'trigger-id'
        results = instance.get_alerts_for(self._trigger)
        self.assertEqual(2, len(results))
        self.assertIsInstance(results[0], Alert)
        self.assertIsInstance(results[1], Alert)

    def test_get_alert_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.get_alert(None, self._trigger)
        with self.assertRaises(AssertionError):
            instance.get_alert(123, self._trigger)
        with self.assertRaises(AssertionError):
            instance.get_alert('alert-id', None)
        with self.assertRaises(AssertionError):
            self._trigger.id = 123
            instance.get_alert('alert-id', self._trigger)

    def test_get_alert(self):
        self._trigger.id = 'trigger-id'
        instance = self.factory(MockHttpClientOneAlert)
        result = instance.get_alert('alert-id', self._trigger)
        self.assertIsInstance(result, Alert)

    def test_delete_all_alerts_for_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.delete_all_alerts_for(None)
        with self.assertRaises(AssertionError):
            self._trigger.id = 123
            instance.delete_all_alerts_for(self._trigger)

    def test_delete_all_alerts_for(self):
        instance = self.factory(MockHttpClientTwoAlerts)
        result = instance.delete_all_alerts_for(self._trigger)
        self.assertIsNone(result)

    def test_delete_alert_fails_with_wrong_input(self):
        instance = AlertManager('APIKey')
        with self.assertRaises(AssertionError):
            instance.delete_alert(None)
        with self.assertRaises(AssertionError):
            self._alert.id = 123
            instance.delete_alert(self._alert)
        self._alert.id = 'alert-id'
        self._alert.trigger_id = None
        with self.assertRaises(AssertionError):
            instance.delete_alert(self._alert)
        self._alert.trigger_id = 789
        with self.assertRaises(AssertionError):
            instance.delete_alert(self._alert)

    def test_delete_alert(self):
        instance = self.factory(MockHttpClientOneAlert)
        result = instance.delete_alert(self._alert)
        self.assertIsNone(result)
    def parse_JSON(self, JSON_string):
        """
        Parses a `pyowm.alertapi30.trigger.Trigger` instance out of raw JSON
        data. As per OWM documentation, start and end times are expressed with
        respect to the moment when you create/update the Trigger. By design,
        PyOWM will only allow users to specify *absolute* datetimes - which is, with the `exact` expression -
        for start/end timestamps (will otherwise result in a `ParseResponseError` be raised)

        :param JSON_string: a raw JSON string
        :type JSON_string: str
        :return: a `pyowm.alertapi30.trigger.Trigger` instance or ``None``
            if no data is available
        :raises: *ParseResponseError* if it is impossible to find or parse the
            data needed to build the result

        """
        if JSON_string is None:
            raise parse_response_error.ParseResponseError('JSON data is None')
        d = json.loads(JSON_string)
        try:
            # trigger id
            trigger_id = d.get('_id', None)

            # start timestamp
            start_dict = d['time_period']['start']
            expr = start_dict['expression']
            if expr != 'after':
                raise ValueError('Invalid time expression: "%s" on start timestamp. Only: "after" is supported' % expr)
            start = start_dict['amount']

            # end timestamp
            end_dict = d['time_period']['end']
            expr = end_dict['expression']
            if expr != 'after':
                raise ValueError('Invalid time expression: "%s" on end timestamp. Only: "after" is supported' % expr)
            end = end_dict['amount']

            # conditions
            conditions = [Condition.from_dict(c) for c in d['conditions']]

            # alerts
            alerts_dict = d['alerts']
            alerts = list()
            for key in alerts_dict:
                alert_id = key
                alert_data = alerts_dict[alert_id]
                alert_last_update = alert_data['last_update']
                alert_met_conds = [
                    dict(current_value=c['current_value']['min'], condition=Condition.from_dict(c['condition']))
                        for c in alert_data['conditions']
                ]
                alert_coords = alert_data['coordinates']
                alert = Alert(alert_id, trigger_id, alert_met_conds, alert_coords, last_update=alert_last_update)
                alerts.append(alert)

            # area
            area_list = d['area']
            area = [GeometryBuilder.build(a_dict) for a_dict in area_list]

            # alert channels
            alert_channels = None  # defaulting

        except ValueError as e:
            raise parse_response_error.ParseResponseError('Impossible to parse JSON: %s' % e)
        except KeyError as e:
            raise parse_response_error.ParseResponseError('Impossible to parse JSON: %s' % e)

        return Trigger(start, end, conditions, area=area, alerts=alerts, alert_channels=alert_channels, id=trigger_id)