def test_importer_values(self):
        try:
            importer = ExternalEventImporter(self.directory)

            string_values = [
                'title', 'short_description', 'long_description', 'locality',
                'street', 'housenumber', 'zipcode', 'town', 'location_url',
                'event_url', 'organizer', 'contact_name', 'contact_email',
                'contact_phone', 'prices', 'registration', 'source_id',
                'fetch_id'
            ]
            now = default_now().replace(microsecond=0)
            then = now + timedelta(days=10)

            event = {s: s for s in string_values}

            event['last_update'] = now
            event['start'] = then
            event['end'] = then + timedelta(hours=1)
            event['timezone'] = default_timezone()
            event['whole_day'] = False
            event['recurrence'] = 'RRULE:FREQ=DAILY;COUNT=2'

            event['cat1'] = set(['c1', 'c2'])
            event['cat2'] = set(['c3', 'c4'])

            event['longitude'] = 7.8673189
            event['latitude'] = 46.6859853

            # :TODO: test image and attachement download
            # event['image'] =
            # event['attachment_1'] =
            # event['attachment_2'] =

            imports, deleted = importer.fetch_one('source', lambda: [event])
            imported = self.catalog.query()
            self.assertEquals(imports, 1)
            self.assertEquals(len(imported), 1)

            imported = imported[0].getObject()
            for s in string_values:
                self.assertTrue(s in vars(imported))
                self.assertTrue(vars(imported)[s] == s)

            self.assertEquals(imported.start, now + timedelta(days=10))
            self.assertEquals(imported.end, now + timedelta(days=10, hours=1))
            self.assertEquals(imported.recurrence, 'RRULE:FREQ=DAILY;COUNT=2')
            self.assertFalse(imported.whole_day)

            self.assertTrue('c1' in imported.cat1)
            self.assertTrue('c2' in imported.cat1)
            self.assertTrue('c3' in imported.cat2)
            self.assertTrue('c4' in imported.cat2)

            self.assertEquals(
                IGeoreferenced(imported).coordinates, [7.8673189, 46.6859853])

        finally:
            # Clean up (transaction has been commited)
            self.cleanup_after_fetch_one()
Exemple #2
0
    def create_fetch_entry(self, **kw):
        def_start = datetime.today().replace(second=0) + timedelta(days=10)
        def_end = def_start + timedelta(hours=1)
        defaults = {
            # from IDirectoryItem
            # description not used
            'title': '',

            # from IEventsDirectoryItem
            # submitter, submitter_email not used
            'short_description': '',
            'long_description': '',
            'image': '',
            'attachment_1': '',
            'attachment_2': '',
            'locality': '',
            'street': '',
            'housenumber': '',
            'zipcode': '',
            'town': '',
            'location_url': '',
            'event_url': '',
            'organizer': '',
            'contact_name': '',
            'contact_email': '',
            'contact_phone': '',
            'prices': '',
            'registration': '',

            # from IExternalEvent
            # source not used (filled in by ExternalEventImporter)
            'source_id': 'id-1',

            # From IEventBasic
            'start': def_start,
            'end': def_end,
            'whole_day': False,
            'timezone': default_timezone(),

            # From IEventRecurrence
            'recurrence': '',

            # additional attributes used to control import
            'fetch_id': 'fetch-1',
            'last_update': default_now().replace(microsecond=0),
            'latitude': '',
            'longitude': '',
            'cat1': set(),
            'cat2': set(),
        }

        for attr in defaults:
            if not attr in kw:
                kw[attr] = defaults[attr]

        return kw
    def create_fetch_entry(self, **kw):
        def_start = datetime.today().replace(second=0) + timedelta(days=10)
        def_end = def_start + timedelta(hours=1)
        defaults = {
            # from IDirectoryItem
            # description not used
            'title': '',

            # from IEventsDirectoryItem
            # submitter, submitter_email not used
            'short_description': '',
            'long_description': '',
            'image': '',
            'attachment_1': '',
            'attachment_2': '',
            'locality': '',
            'street': '',
            'housenumber': '',
            'zipcode': '',
            'town': '',
            'location_url': '',
            'event_url': '',
            'organizer': '',
            'contact_name': '',
            'contact_email': '',
            'contact_phone': '',
            'prices': '',
            'registration': '',

            # from IExternalEvent
            # source not used (filled in by ExternalEventImporter)
            'source_id': 'id-1',

            # From IEventBasic
            'start': def_start,
            'end': def_end,
            'whole_day': False,
            'timezone': default_timezone(),

            # From IEventRecurrence
            'recurrence': '',

            # additional attributes used to control import
            'fetch_id': 'fetch-1',
            'last_update': default_now().replace(microsecond=0),
            'latitude': '',
            'longitude': '',
            'cat1': set(),
            'cat2': set(),
        }

        for attr in defaults:
            if not attr in kw:
                kw[attr] = defaults[attr]

        return kw
    def create_fetch_entry(self, **kw):
        def_start = datetime.today().replace(second=0) + timedelta(days=10)
        def_end = def_start + timedelta(hours=1)
        defaults = {
            # from IDirectoryItem
            # description not used
            "title": "",
            # from IEventsDirectoryItem
            # submitter, submitter_email not used
            "short_description": "",
            "long_description": "",
            "image": "",
            "attachment_1": "",
            "attachment_2": "",
            "locality": "",
            "street": "",
            "housenumber": "",
            "zipcode": "",
            "town": "",
            "location_url": "",
            "event_url": "",
            "organizer": "",
            "contact_name": "",
            "contact_email": "",
            "contact_phone": "",
            "prices": "",
            "registration": "",
            # from IExternalEvent
            # source not used (filled in by ExternalEventImporter)
            "source_id": "id-1",
            # From IEventBasic
            "start": def_start,
            "end": def_end,
            "whole_day": False,
            "timezone": default_timezone(),
            # From IEventRecurrence
            "recurrence": "",
            # additional attributes used to control import
            "fetch_id": "fetch-1",
            "last_update": default_now().replace(microsecond=0),
            "latitude": "",
            "longitude": "",
            "cat1": set(),
            "cat2": set(),
        }

        for attr in defaults:
            if attr not in kw:
                kw[attr] = defaults[attr]

        return kw
    def test_importer_update_time(self):
        importer = ExternalEventImporter(self.directory)

        set_time = lambda t: importer.set_last_update_time(t)
        get_time = lambda: importer.get_last_update_time()

        # No key
        self.assertRaises(AttributeError, get_time)
        self.assertRaises(AttributeError, set_time, default_now())
        self.assertRaises(AttributeError, get_time)

        importer.annotation_key = 'key'

        # Wrong dates
        self.assertRaises(AssertionError, set_time, None)
        self.assertRaises(AssertionError, set_time, 25)
        self.assertRaises(AssertionError, set_time, datetime.today())

        # Ok
        update = default_now()
        importer.set_last_update_time(update)
        last_update = importer.get_last_update_time()
        self.assertEquals(last_update, update.replace(microsecond=0))
    def test_importer_update_time(self):
        importer = ExternalEventImporter(self.directory)

        set_time = lambda t: importer.set_last_update_time(t)
        get_time = lambda: importer.get_last_update_time()

        # No key
        self.assertRaises(AttributeError, get_time)
        self.assertRaises(AttributeError, set_time, default_now())
        self.assertRaises(AttributeError, get_time)

        importer.annotation_key = 'key'

        # Wrong dates
        self.assertRaises(AssertionError, set_time, None)
        self.assertRaises(AssertionError, set_time, 25)
        self.assertRaises(AssertionError, set_time, datetime.today())

        # Ok
        update = default_now()
        importer.set_last_update_time(update)
        last_update = importer.get_last_update_time()
        self.assertEquals(last_update, update.replace(microsecond=0))
    def test_seantis_import(self):
        json_string = """[{
            "id": "id1", "title": "title",
            "short_description": "short_description",
            "long_description": "h\u00e4nsel",
            "cat1": ["cat12", "cat11"], "cat2": ["cat21"],
            "event_url": "http://www.event.ch",
            "timezone": "Europe/Zurich",
            "start": "2014-01-15T00:00:00+00:00",
            "end": "2014-01-15T23:59:59+00:00",
            "whole_day": true,
            "recurrence": "RRULE:FREQ=WEEKLY;BYDAY=MO,TU;UNTIL=20150101T0000Z",
            "locality": "locality",
            "street": "street", "housenumber": "housenumber",
            "zipcode": "1234", "town": "town",
            "longitude": 2.0, "latitude": 1.0,
            "location_url": "http://www.location.ch",
            "contact_name": "contact_name",
            "contact_phone": "+12 (3) 45 678 90 12",
            "contact_email": "*****@*****.**",
            "registration": "http://www.tickets.ch",
            "organizer": "organizer",
            "prices": "prices",
            "images": [{"url": "img_url", "name": "img_name"}],
            "attachements": [
                {"url": "a1_url", "name": "a1_name"},
                {"url": "a2_url", "name": "a2_name"}
            ],
            "submitter": "sumitter", "submitter_email": "*****@*****.**"
        },{
            "last_update": "2014-01-21T10:21:47+01:00",
            "id": "test", "title": "test",
            "short_description": "test", "long_description": null,
            "cat1": ["cat13", "cat14"], "cat2": ["cat21", "cat22", "cat23"],
            "event_url": null,
            "timezone": "UTC",
            "start": "2014-01-19T17:00:00+02:00",
            "end": "2014-01-19T18:00:00+02:00",
            "whole_day": false, "recurrence": null,
            "locality": null, "street": null, "housenumber": null,
            "zipcode": null, "town": null,
            "longitude": null, "latitude": null,
            "location_url": null,
            "contact_name": null, "contact_phone": null, "contact_email": null,
            "registration": null, "organizer": null, "prices": null,
            "images": null, "attachments": [],
            "submitter": "cccc", "submitter_email": "*****@*****.**"
        }]"""

        context = mock.Mock()
        context.url = 'url'
        context.do_filter = False
        context.cat1 = ''
        context.cat2 = ''

        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 2)

        self.assertTrue(
            default_now() - events[0]['last_update'] < timedelta(seconds=10))
        self.assertEquals(events[0]['fetch_id'], 'url')
        self.assertEquals(events[0]['id'], 'id1')
        self.assertEquals(events[0]['source_id'], 'id1')
        self.assertEquals(events[0]['title'], 'title')
        self.assertEquals(events[0]['short_description'], u'short_description')
        self.assertEquals(events[0]['long_description'], u'h\xe4nsel')
        self.assertEquals(events[0]['event_url'], 'http://www.event.ch')
        self.assertEquals(events[0]['registration'], 'http://www.tickets.ch')
        self.assertEquals(events[0]['location_url'], 'http://www.location.ch')
        self.assertEquals(events[0]['image'], 'img_url')
        self.assertEquals(events[0]['image_name'], 'img_name')
        self.assertEquals(events[0]['attachment_1'], 'a1_url')
        self.assertEquals(events[0]['attachment_1_name'], 'a1_name')
        self.assertEquals(events[0]['attachment_2'], 'a2_url')
        self.assertEquals(events[0]['attachment_2_name'], 'a2_name')
        self.assertEquals(events[0]['organizer'], 'organizer')
        self.assertEquals(events[0]['street'], 'street')
        self.assertEquals(events[0]['housenumber'], 'housenumber')
        self.assertEquals(events[0]['locality'], 'locality')
        self.assertEquals(events[0]['zipcode'], '1234')
        self.assertEquals(events[0]['town'], 'town')
        self.assertEquals(events[0]['contact_name'], 'contact_name')
        self.assertEquals(events[0]['contact_email'], '*****@*****.**')
        self.assertEquals(events[0]['contact_phone'], '+12 (3) 45 678 90 12')
        self.assertEquals(events[0]['latitude'], '1.0')
        self.assertEquals(events[0]['longitude'], '2.0')
        self.assertEquals(events[0]['timezone'], 'Europe/Zurich')
        self.assertEquals(events[0]['start'],
                          datetime(2014, 1, 15, 0, 0, tzinfo=pytz.UTC))
        self.assertEquals(events[0]['end'],
                          datetime(2014, 1, 15, 23, 59, 59, tzinfo=pytz.UTC))
        self.assertEquals(
            events[0]['recurrence'],
            'RRULE:FREQ=WEEKLY;BYDAY=MO,TU;UNTIL=20150101T0000Z')
        self.assertEquals(events[0]['whole_day'], True)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))
        self.assertEquals(events[0]['cat2'], set(['cat21']))
        self.assertEquals(events[0]['submitter'], 'sumitter')
        self.assertEquals(events[0]['submitter_email'], '*****@*****.**')

        self.assertEquals(events[1]['last_update'],
                          datetime(2014, 1, 21, 9, 21, 47, tzinfo=pytz.UTC))
        self.assertEquals(events[1]['latitude'], None)
        self.assertEquals(events[1]['longitude'], None)
        self.assertEquals(events[1]['timezone'], 'UTC')
        self.assertEquals(events[1]['start'],
                          datetime(2014, 1, 19, 15, 0, tzinfo=pytz.UTC))
        self.assertEquals(events[1]['end'],
                          datetime(2014, 1, 19, 16, 0, tzinfo=pytz.UTC))
        self.assertEquals(events[1]['whole_day'], False)
        self.assertEquals(events[1]['cat1'], set(['cat13', 'cat14']))
        self.assertEquals(events[1]['cat2'], set(['cat21', 'cat22', 'cat23']))

        # Filter by categories
        context.do_filter = False
        context.cat1 = 'cat5'
        context.cat2 = 'cat6'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 2)

        context.do_filter = True

        context.cat1 = ''
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 2)

        context.cat1 = 'cat1'
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 0)

        context.cat1 = 'cat11'
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))

        context.cat1 = 'cat12'
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))

        context.cat1 = ''
        context.cat2 = 'cat23'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat2'], set(['cat21', 'cat22', 'cat23']))

        context.cat1 = ''
        context.cat2 = 'cat24'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 0)

        context.do_filter = True
        context.cat1 = 'cat11'
        context.cat2 = 'cat21'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))
        self.assertEquals(events[0]['cat2'], set(['cat21']))
    def fetch(self, json_string=None):

        try:
            if json_string is None:
                url = self.build_url()
                json_string = urlopen(url, timeout=300).read()

            events = json.loads(json_string)
        except:
            raise NoImportDataException()

        for event in events:

            cat1, cat2 = event.get('cat1'), event.get('cat2')
            cat1 = set(cat1) if cat1 is not None else set()
            cat2 = set(cat2) if cat2 is not None else set()

            if self.context.do_filter:
                if self.context.cat1:
                    if self.context.cat1:
                        if self.context.cat1 not in cat1:
                            continue
                    else:
                        continue
                if self.context.cat2:
                    if self.context.cat2:
                        if self.context.cat2 not in cat2:
                            continue
                    else:
                        continue

            e = {}
            e['fetch_id'] = self.context.url
            updated = event.get('last_update')
            e['last_update'] = parse(updated) if updated else default_now()
            e['source_id'] = event['id']

            e['id'] = event.get('id')
            e['title'] = event.get('title')
            e['short_description'] = event.get('short_description')
            e['long_description'] = event.get('long_description')
            e['cat1'] = cat1
            e['cat2'] = cat2

            timezone = event.get('timezone')
            start = fix_tzinfo(parse(event.get('start')))
            end = fix_tzinfo(parse(event.get('end')))

            e['timezone'] = timezone
            e['start'] = as_timezone(start, timezone)
            e['end'] = as_timezone(end, timezone)
            e['recurrence'] = event.get('recurrence')
            e['whole_day'] = event.get('whole_day')

            e['locality'] = event.get('locality')
            e['street'] = event.get('street')
            e['housenumber'] = event.get('housenumber')
            e['zipcode'] = event.get('zipcode')
            e['town'] = event.get('town')
            e['location_url'] = event.get('location_url')
            lon, lat = event.get('longitude'), event.get('latitude')
            e['longitude'] = str(lon) if lon is not None else None
            e['latitude'] = str(lat) if lon is not None else None
            e['organizer'] = event.get('organizer')
            e['contact_name'] = event.get('contact_name')
            e['contact_email'] = event.get('contact_email')
            e['contact_phone'] = event.get('contact_phone')
            e['prices'] = event.get('prices')
            e['event_url'] = event.get('event_url')
            e['registration'] = event.get('registration')
            e['submitter'] = event.get('submitter')
            e['submitter_email'] = event.get('submitter_email')

            try:
                e['image'] = event['images'][0]['url']
                e['image_name'] = event['images'][0]['name']
            except (TypeError, KeyError, IndexError):
                e['image'] = None

            try:
                e['attachment_1'] = event['attachements'][0]['url']
                e['attachment_1_name'] = event['attachements'][0]['name']
            except (TypeError, KeyError, IndexError):
                e['attachment_1'] = None
            try:
                e['attachment_2'] = event['attachements'][1]['url']
                e['attachment_2_name'] = event['attachements'][1]['name']
            except (TypeError, KeyError, IndexError):
                e['attachment_2'] = None

            yield e
    def fetch(self, json_string=None):

        try:
            if json_string is None:
                url = self.build_url()
                json_string = urlopen(url, timeout=300).read()

            events = json.loads(json_string)
        except:
            raise NoImportDataException()

        for event in events:

            cat1, cat2 = event.get('cat1'), event.get('cat2')
            cat1 = set(cat1) if cat1 is not None else set()
            cat2 = set(cat2) if cat2 is not None else set()

            if self.context.do_filter:
                if self.context.cat1:
                    if self.context.cat1:
                        if self.context.cat1 not in cat1:
                            continue
                    else:
                        continue
                if self.context.cat2:
                    if self.context.cat2:
                        if self.context.cat2 not in cat2:
                            continue
                    else:
                        continue

            e = {}
            e['fetch_id'] = self.context.url
            updated = event.get('last_update')
            e['last_update'] = parse(updated) if updated else default_now()
            e['source_id'] = event['id']

            e['id'] = event.get('id')
            e['title'] = event.get('title')
            e['short_description'] = event.get('short_description')
            e['long_description'] = event.get('long_description')
            e['cat1'] = cat1
            e['cat2'] = cat2

            timezone = event.get('timezone')
            start = fix_tzinfo(parse(event.get('start')))
            end = fix_tzinfo(parse(event.get('end')))

            e['timezone'] = timezone
            e['start'] = as_timezone(start, timezone)
            e['end'] = as_timezone(end, timezone)
            e['recurrence'] = event.get('recurrence')
            e['whole_day'] = event.get('whole_day')

            e['locality'] = event.get('locality')
            e['street'] = event.get('street')
            e['housenumber'] = event.get('housenumber')
            e['zipcode'] = event.get('zipcode')
            e['town'] = event.get('town')
            e['location_url'] = event.get('location_url')
            lon, lat = event.get('longitude'), event.get('latitude')
            e['longitude'] = str(lon) if lon is not None else None
            e['latitude'] = str(lat) if lon is not None else None
            e['organizer'] = event.get('organizer')
            e['contact_name'] = event.get('contact_name')
            e['contact_email'] = event.get('contact_email')
            e['contact_phone'] = event.get('contact_phone')
            e['prices'] = event.get('prices')
            e['event_url'] = event.get('event_url')
            e['registration'] = event.get('registration')
            e['submitter'] = event.get('submitter')
            e['submitter_email'] = event.get('submitter_email')

            try:
                e['image'] = event['images'][0]['url']
                e['image_name'] = event['images'][0]['name']
            except (TypeError, KeyError, IndexError):
                e['image'] = None

            try:
                e['attachment_1'] = event['attachements'][0]['url']
                e['attachment_1_name'] = event['attachements'][0]['name']
            except (TypeError, KeyError, IndexError):
                e['attachment_1'] = None
            try:
                e['attachment_2'] = event['attachements'][1]['url']
                e['attachment_2_name'] = event['attachements'][1]['name']
            except (TypeError, KeyError, IndexError):
                e['attachment_2'] = None

            yield e
    def test_seantis_import(self):
        json_string = """[{
            "id": "id1", "title": "title",
            "short_description": "short_description",
            "long_description": "h\u00e4nsel",
            "cat1": ["cat12", "cat11"], "cat2": ["cat21"],
            "event_url": "http://www.event.ch",
            "timezone": "Europe/Zurich",
            "start": "2014-01-15T00:00:00+00:00",
            "end": "2014-01-15T23:59:59+00:00",
            "whole_day": true,
            "recurrence": "RRULE:FREQ=WEEKLY;BYDAY=MO,TU;UNTIL=20150101T0000Z",
            "locality": "locality",
            "street": "street", "housenumber": "housenumber",
            "zipcode": "1234", "town": "town",
            "longitude": 2.0, "latitude": 1.0,
            "location_url": "http://www.location.ch",
            "contact_name": "contact_name",
            "contact_phone": "+12 (3) 45 678 90 12",
            "contact_email": "*****@*****.**",
            "registration": "http://www.tickets.ch",
            "organizer": "organizer",
            "prices": "prices",
            "images": [{"url": "img_url", "name": "img_name"}],
            "attachements": [
                {"url": "a1_url", "name": "a1_name"},
                {"url": "a2_url", "name": "a2_name"}
            ],
            "submitter": "sumitter", "submitter_email": "*****@*****.**"
        },{
            "last_update": "2014-01-21T10:21:47+01:00",
            "id": "test", "title": "test",
            "short_description": "test", "long_description": null,
            "cat1": ["cat13", "cat14"], "cat2": ["cat21", "cat22", "cat23"],
            "event_url": null,
            "timezone": "UTC",
            "start": "2014-01-19T17:00:00+02:00",
            "end": "2014-01-19T18:00:00+02:00",
            "whole_day": false, "recurrence": null,
            "locality": null, "street": null, "housenumber": null,
            "zipcode": null, "town": null,
            "longitude": null, "latitude": null,
            "location_url": null,
            "contact_name": null, "contact_phone": null, "contact_email": null,
            "registration": null, "organizer": null, "prices": null,
            "images": null, "attachments": [],
            "submitter": "cccc", "submitter_email": "*****@*****.**"
        }]"""

        context = mock.Mock()
        context.url = 'url'
        context.do_filter = False
        context.cat1 = ''
        context.cat2 = ''

        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 2)

        self.assertTrue(
            default_now() - events[0]['last_update'] < timedelta(seconds=10)
        )
        self.assertEquals(events[0]['fetch_id'], 'url')
        self.assertEquals(events[0]['id'], 'id1')
        self.assertEquals(events[0]['source_id'], 'id1')
        self.assertEquals(events[0]['title'], 'title')
        self.assertEquals(events[0]['short_description'], u'short_description')
        self.assertEquals(events[0]['long_description'], u'h\xe4nsel')
        self.assertEquals(events[0]['event_url'], 'http://www.event.ch')
        self.assertEquals(events[0]['registration'], 'http://www.tickets.ch')
        self.assertEquals(events[0]['location_url'], 'http://www.location.ch')
        self.assertEquals(events[0]['image'], 'img_url')
        self.assertEquals(events[0]['image_name'], 'img_name')
        self.assertEquals(events[0]['attachment_1'], 'a1_url')
        self.assertEquals(events[0]['attachment_1_name'], 'a1_name')
        self.assertEquals(events[0]['attachment_2'], 'a2_url')
        self.assertEquals(events[0]['attachment_2_name'], 'a2_name')
        self.assertEquals(events[0]['organizer'], 'organizer')
        self.assertEquals(events[0]['street'], 'street')
        self.assertEquals(events[0]['housenumber'], 'housenumber')
        self.assertEquals(events[0]['locality'], 'locality')
        self.assertEquals(events[0]['zipcode'], '1234')
        self.assertEquals(events[0]['town'], 'town')
        self.assertEquals(events[0]['contact_name'], 'contact_name')
        self.assertEquals(events[0]['contact_email'], '*****@*****.**')
        self.assertEquals(events[0]['contact_phone'], '+12 (3) 45 678 90 12')
        self.assertEquals(events[0]['latitude'], '1.0')
        self.assertEquals(events[0]['longitude'], '2.0')
        self.assertEquals(events[0]['timezone'], 'Europe/Zurich')
        self.assertEquals(events[0]['start'], datetime(2014, 1, 15, 0, 0,
                                                       tzinfo=pytz.UTC))
        self.assertEquals(events[0]['end'], datetime(2014, 1, 15, 23, 59, 59,
                                                     tzinfo=pytz.UTC))
        self.assertEquals(events[0]['recurrence'],
                          'RRULE:FREQ=WEEKLY;BYDAY=MO,TU;UNTIL=20150101T0000Z')
        self.assertEquals(events[0]['whole_day'], True)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))
        self.assertEquals(events[0]['cat2'], set(['cat21']))
        self.assertEquals(events[0]['submitter'], 'sumitter')
        self.assertEquals(events[0]['submitter_email'], '*****@*****.**')

        self.assertEquals(
            events[1]['last_update'],
            datetime(2014, 1, 21, 9, 21, 47, tzinfo=pytz.UTC)
        )
        self.assertEquals(events[1]['latitude'], None)
        self.assertEquals(events[1]['longitude'], None)
        self.assertEquals(events[1]['timezone'], 'UTC')
        self.assertEquals(events[1]['start'], datetime(2014, 1, 19, 15, 0,
                                                       tzinfo=pytz.UTC))
        self.assertEquals(events[1]['end'], datetime(2014, 1, 19, 16, 0,
                                                     tzinfo=pytz.UTC))
        self.assertEquals(events[1]['whole_day'], False)
        self.assertEquals(events[1]['cat1'], set(['cat13', 'cat14']))
        self.assertEquals(events[1]['cat2'], set(['cat21', 'cat22', 'cat23']))

        # Filter by categories
        context.do_filter = False
        context.cat1 = 'cat5'
        context.cat2 = 'cat6'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 2)

        context.do_filter = True

        context.cat1 = ''
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 2)

        context.cat1 = 'cat1'
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 0)

        context.cat1 = 'cat11'
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))

        context.cat1 = 'cat12'
        context.cat2 = ''
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))

        context.cat1 = ''
        context.cat2 = 'cat23'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat2'], set(['cat21', 'cat22', 'cat23']))

        context.cat1 = ''
        context.cat2 = 'cat24'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 0)

        context.do_filter = True
        context.cat1 = 'cat11'
        context.cat2 = 'cat21'
        source = EventsSourceSeantisJson(context)
        events = [event for event in source.fetch(json_string)]
        self.assertEquals(len(events), 1)
        self.assertEquals(events[0]['cat1'], set(['cat11', 'cat12']))
        self.assertEquals(events[0]['cat2'], set(['cat21']))
    def test_importer_values(self):
        try:
            importer = ExternalEventImporter(self.directory)

            string_values = [
                'title', 'short_description', 'long_description',
                'locality', 'street', 'housenumber', 'zipcode', 'town',
                'location_url', 'event_url', 'organizer',
                'contact_name', 'contact_email', 'contact_phone',
                'prices', 'registration',
                'source_id', 'fetch_id'
            ]
            now = default_now().replace(
                year=2015, month=1, day=1, microsecond=0
            )
            then = now + timedelta(days=10)

            event = {s: s for s in string_values}

            event['last_update'] = now
            event['start'] = then
            event['end'] = then + timedelta(hours=1)
            event['timezone'] = default_timezone()
            event['whole_day'] = False
            event['recurrence'] = 'RRULE:FREQ=DAILY;COUNT=2'

            event['cat1'] = set(['c1', 'c2'])
            event['cat2'] = set(['c3', 'c4'])

            event['longitude'] = 7.8673189
            event['latitude'] = 46.6859853

            # :TODO: test image and attachement download
            # event['image'] =
            # event['attachment_1'] =
            # event['attachment_2'] =

            imports, deleted = importer.fetch_one('source', lambda: [event])
            imported = self.catalog.query()
            self.assertEquals(imports, 1)
            self.assertEquals(len(imported), 1)

            imported = imported[0].getObject()
            for s in string_values:
                self.assertTrue(s in vars(imported))
                self.assertTrue(vars(imported)[s] == s)

            self.assertEquals(imported.start, now + timedelta(days=10))
            self.assertEquals(imported.end, now + timedelta(days=10, hours=1))
            self.assertEquals(imported.recurrence, 'RRULE:FREQ=DAILY;COUNT=2')
            self.assertFalse(imported.whole_day)

            self.assertTrue('c1' in imported.cat1)
            self.assertTrue('c2' in imported.cat1)
            self.assertTrue('c3' in imported.cat2)
            self.assertTrue('c4' in imported.cat2)

            self.assertEquals(
                IGeoreferenced(imported).coordinates, [7.8673189, 46.6859853]
            )

        finally:
            # Clean up (transaction has been commited)
            self.cleanup_after_fetch_one()