示例#1
0
    def test_oneEventCalendar(self):
        """
        Exporting an calendar with one event in it will result in just that
        event.
        """
        yield populateCalendarsFrom(
            {
                "user01": {
                    "calendar1": {
                        "valentines-day.ics": (valentines, {})
                    }
                }
            }, self.store
        )

        expected = Component.newCalendar()
        [theComponent] = Component.fromString(valentines).subcomponents()
        expected.addComponent(theComponent)

        io = StringIO()
        yield exportToFile(
            [(yield self.txn().calendarHomeWithUID("user01"))
                .calendarWithName("calendar1")], io
        )
        self.assertEquals(Component.fromString(io.getvalue()),
                          expected)
示例#2
0
    def createConflicted(self, c1=None, c2=None):
        """
        Create two calendar homes with calendars with the same names within
        them.  Parameters are both a mapping of calendar object names to
        2-tuples of (iCalendar data, metadata).

        @param c1: the calendar data for conflict1/conflicted/*

        @param c2: the calendar data for conflict2/conflicted/*
        """
        if c1 is None:
            c1 = {"1.ics": self.sampleEvent("uid1")}
        if c2 is None:
            c2 = {"2.ics": self.sampleEvent("uid2")}
        defaults = {"calendar": {}, "inbox": {}, "tasks": {}, "polls": {}}

        def conflicted(caldata):
            d = defaults.copy()
            d.update(conflicted=caldata)
            return d

        yield populateCalendarsFrom(
            {
                "conflict1": conflicted(c1),
                "conflict2": conflicted(c2),
            }, self.storeUnderTest())
示例#3
0
    def test_twoSimpleEvents(self):
        """
        Exporting a calendar with two events in it will result in a VCALENDAR
        component with both VEVENTs in it.
        """
        yield populateCalendarsFrom(
            {
                "user01": {
                    "calendar1": {
                        "valentines-day.ics": (valentines, {}),
                        "new-years-day.ics": (newYears, {})
                    }
                }
            }, self.store)

        expected = Component.newCalendar()
        a = Component.fromString(valentines)
        b = Component.fromString(newYears)
        for comp in a, b:
            for sub in comp.subcomponents():
                expected.addComponent(sub)

        io = StringIO()
        yield exportToFile([(yield self.txn().calendarHomeWithUID("user01")
                             ).calendarWithName("calendar1")], io)
        self.assertEquals(Component.fromString(io.getvalue()), expected)
示例#4
0
    def test_migrateEmptyHome(self):
        """
        Migrating an empty home into an existing home should destroy all the
        existing home's calendars.
        """
        yield populateCalendarsFrom({
            "empty_home": {
                # Some of the upgrade logic will ensure that sufficient default
                # calendars exist for basic usage, so this home is actually only
                # *mostly* empty; the important thing is that the default
                # calendar is removed.
                "other-default-calendar": {}
            },
            "non_empty_home": {
                "calendar": {},
                "inbox": {},
                # XXX: implementation is configuration-sensitive regarding the
                # 'tasks' calendar and it shouldn't be.
                "tasks": {},
                "polls": {},
            }
        }, self.storeUnderTest())
        txn = self.transactionUnderTest()
        emptyHome = yield txn.calendarHomeWithUID("empty_home")
        self.assertIdentical((yield emptyHome.calendarWithName("calendar")), None)
        nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")
        yield migrateHome(emptyHome, nonEmpty)
        yield self.commit()
        txn = self.transactionUnderTest()
        emptyHome = yield txn.calendarHomeWithUID("empty_home")
        nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")

        self.assertIdentical((yield nonEmpty.calendarWithName("calendar")), None)
        self.assertNotIdentical((yield nonEmpty.calendarWithName("inbox")), None)
        self.assertNotIdentical((yield nonEmpty.calendarWithName("other-default-calendar")), None)
示例#5
0
        def test_exportAll(self):
            """
            Run the export with --all to get a directory of calendars from all
            calendar homes in the database.
            """
            yield populateCalendarsFrom(
                {
                    "user01": {
                        "calendar1": {
                            "valentines-day.ics": (valentines, {}),
                            "new-years-day.ics": (newYears, {})
                        }
                    },
                    "user02": {
                        "calendar1": {
                            "valentines-day.ics": (valentines, {})
                        },
                        "calendar2": {
                            "new-years-day.ics": (newYears, {})
                        }
                    }
                }, self.store)

            outputDir = FilePath(self.mktemp())
            outputDir.makedirs()
            main([
                'calendarserver_export', '--directory', outputDir.path, '--all'
            ],
                 reactor=self)
            yield self.waitToStop
            self.assertEquals(
                set([
                    "user01_calendar1.ics", "user02_calendar1.ics",
                    "user02_calendar2.ics"
                ]), set([child.basename() for child in outputDir.children()]))
示例#6
0
    def test_full(self):
        """
        Running C{calendarserver_export} on the command line exports an ics
        file. (Almost-full integration test, starting from the main point, using
        as few test fakes as possible.)

        Note: currently the only test for directory interaction.
        """
        yield populateCalendarsFrom(
            {
                "user02": {
                    # TODO: more direct test for skipping inbox
                    "inbox": {
                        "inbox-item.ics": (valentines, {})
                    },
                    "calendar1": {
                        "peruser.ics": (dataForTwoUsers, {}), # EST
                    }
                }
            }, self.store
        )

        output = FilePath(self.mktemp())
        main(['calendarserver_export', '--output',
              output.path, '--user', 'user02'], reactor=self)

        yield self.waitToStop

        self.assertEquals(
            Component.fromString(resultForUser2),
            Component.fromString(output.getContent())
        )
示例#7
0
    def test_full(self):
        """
        Running C{calendarserver_export} on the command line exports an ics
        file. (Almost-full integration test, starting from the main point, using
        as few test fakes as possible.)

        Note: currently the only test for directory interaction.
        """
        yield populateCalendarsFrom(
            {
                "user02": {
                    # TODO: more direct test for skipping inbox
                    "inbox": {
                        "inbox-item.ics": (valentines, {})
                    },
                    "calendar1": {
                        "peruser.ics": (dataForTwoUsers, {}),  # EST
                    }
                }
            },
            self.store)

        output = FilePath(self.mktemp())
        main([
            'calendarserver_export', '--output', output.path, '--user',
            'user02'
        ],
             reactor=self)

        yield self.waitToStop

        self.assertEquals(Component.fromString(resultForUser2),
                          Component.fromString(output.getContent()))
示例#8
0
    def test_migrateEmptyHome(self):
        """
        Migrating an empty home into an existing home should destroy all the
        existing home's calendars.
        """
        yield populateCalendarsFrom({
            "empty_home": {
                # Some of the upgrade logic will ensure that sufficient default
                # calendars exist for basic usage, so this home is actually only
                # *mostly* empty; the important thing is that the default
                # calendar is removed.
                "other-default-calendar": {}
            },
            "non_empty_home": {
                "calendar": {},
                "inbox": {},
                # XXX: implementation is configuration-sensitive regarding the
                # 'tasks' calendar and it shouldn't be.
                "tasks": {},
                "polls": {},
            }
        }, self.storeUnderTest())
        txn = self.transactionUnderTest()
        emptyHome = yield txn.calendarHomeWithUID("empty_home")
        self.assertIdentical((yield emptyHome.calendarWithName("calendar")), None)
        nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")
        yield migrateHome(emptyHome, nonEmpty)
        yield self.commit()
        txn = self.transactionUnderTest()
        emptyHome = yield txn.calendarHomeWithUID("empty_home")
        nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")

        self.assertIdentical((yield nonEmpty.calendarWithName("calendar")), None)
        self.assertNotIdentical((yield nonEmpty.calendarWithName("inbox")), None)
        self.assertNotIdentical((yield nonEmpty.calendarWithName("other-default-calendar")), None)
示例#9
0
    def setUp(self):
        """
        Set up two stores to migrate between.
        """
        # Add some files to the file store.

        self.filesPath = CachingFilePath(self.mktemp())
        self.filesPath.createDirectory()
        fileStore = self.fileStore = CommonDataStore(
            self.filesPath, {"push": StubNotifierFactory()}, TestStoreDirectoryService(), True, True
        )
        self.sqlStore = yield theStoreBuilder.buildStore(
            self, StubNotifierFactory()
        )
        self.upgrader = UpgradeToDatabaseStep(self.fileStore, self.sqlStore)

        requirements = CommonTests.requirements
        extras = deriveValue(self, "extraRequirements", lambda t: {})
        requirements = self.mergeRequirements(requirements, extras)

        yield populateCalendarsFrom(requirements, fileStore)
        md5s = CommonTests.md5s
        yield resetCalendarMD5s(md5s, fileStore)
        self.filesPath.child("calendars").child(
            "__uids__").child("ho").child("me").child("home1").child(
            ".some-extra-data").setContent("some extra data")

        requirements = ABCommonTests.requirements
        yield populateAddressBooksFrom(requirements, fileStore)
        md5s = ABCommonTests.md5s
        yield resetAddressBookMD5s(md5s, fileStore)
        self.filesPath.child("addressbooks").child(
            "__uids__").child("ho").child("me").child("home1").child(
            ".some-extra-data").setContent("some extra data")
示例#10
0
    def test_oneEventCalendar(self):
        """
        Exporting an calendar with one event in it will result in just that
        event.
        """
        yield populateCalendarsFrom(
            {
                "home1": {
                    "calendar1": {
                        "valentines-day.ics": (valentines, {})
                    }
                }
            }, self.store
        )

        expected = Component.newCalendar()
        [theComponent] = Component.fromString(valentines).subcomponents()
        expected.addComponent(theComponent)

        io = StringIO()
        yield exportToFile(
            [(yield self.txn().calendarHomeWithUID("home1"))
              .calendarWithName("calendar1")], io
        )
        self.assertEquals(Component.fromString(io.getvalue()),
                          expected)
示例#11
0
    def test_twoSimpleEvents(self):
        """
        Exporting a calendar with two events in it will result in a VCALENDAR
        component with both VEVENTs in it.
        """
        yield populateCalendarsFrom(
            {
                "home1": {
                    "calendar1": {
                        "valentines-day.ics": (valentines, {}),
                        "new-years-day.ics": (newYears, {})
                    }
                }
            }, self.store
        )

        expected = Component.newCalendar()
        a = Component.fromString(valentines)
        b = Component.fromString(newYears)
        for comp in a, b:
            for sub in comp.subcomponents():
                expected.addComponent(sub)

        io = StringIO()
        yield exportToFile(
            [(yield self.txn().calendarHomeWithUID("home1"))
              .calendarWithName("calendar1")], io
        )
        self.assertEquals(Component.fromString(io.getvalue()),
                          expected)
    def setUp(self):
        """
        Set up two stores to migrate between.
        """
        # Add some files to the file store.

        self.filesPath = CachingFilePath(self.mktemp())
        self.filesPath.createDirectory()
        fileStore = self.fileStore = CommonDataStore(
            self.filesPath, {"push": StubNotifierFactory()}, TestStoreDirectoryService(), True, True
        )
        self.sqlStore = yield theStoreBuilder.buildStore(
            self, StubNotifierFactory()
        )
        self.upgrader = UpgradeToDatabaseStep(self.fileStore, self.sqlStore)

        requirements = CommonTests.requirements
        extras = deriveValue(self, "extraRequirements", lambda t: {})
        requirements = self.mergeRequirements(requirements, extras)

        yield populateCalendarsFrom(requirements, fileStore)
        md5s = CommonTests.md5s
        yield resetCalendarMD5s(md5s, fileStore)
        self.filesPath.child("calendars").child(
            "__uids__").child("ho").child("me").child("home1").child(
            ".some-extra-data").setContent("some extra data")

        requirements = ABCommonTests.requirements
        yield populateAddressBooksFrom(requirements, fileStore)
        md5s = ABCommonTests.md5s
        yield resetAddressBookMD5s(md5s, fileStore)
        self.filesPath.child("addressbooks").child(
            "__uids__").child("ho").child("me").child("home1").child(
            ".some-extra-data").setContent("some extra data")

        # Add some properties we want to check get migrated over
        txn = self.fileStore.newTransaction()
        home = yield txn.calendarHomeWithUID("home_defaults")

        cal = yield home.calendarWithName("calendar_1")
        props = cal.properties()
        props[PropertyName.fromElement(caldavxml.SupportedCalendarComponentSet)] = caldavxml.SupportedCalendarComponentSet(
            caldavxml.CalendarComponent(name="VEVENT"),
            caldavxml.CalendarComponent(name="VTODO"),
        )
        props[PropertyName.fromElement(element.ResourceType)] = element.ResourceType(
            element.Collection(),
            caldavxml.Calendar(),
        )
        props[PropertyName.fromElement(customxml.GETCTag)] = customxml.GETCTag.fromString("foobar")

        inbox = yield home.calendarWithName("inbox")
        props = inbox.properties()
        props[PropertyName.fromElement(customxml.CalendarAvailability)] = customxml.CalendarAvailability.fromString(str(self.av1))
        props[PropertyName.fromElement(caldavxml.ScheduleDefaultCalendarURL)] = caldavxml.ScheduleDefaultCalendarURL(
            element.HRef.fromString("/calendars/__uids__/home_defaults/calendar_1"),
        )

        yield txn.commit()
示例#13
0
    def test_full(self):
        """
        Running C{calendarserver_export} on the command line exports an ics
        file. (Almost-full integration test, starting from the main point, using
        as few test fakes as possible.)

        Note: currently the only test for directory interaction.
        """
        yield populateCalendarsFrom(
            {
                "user02": {
                    # TODO: more direct test for skipping inbox
                    "inbox": {
                        "inbox-item.ics": (valentines, {})
                    },
                    "calendar1": {
                        "peruser.ics": (dataForTwoUsers, {}), # EST
                    }
                }
            }, self.store
        )

        augmentsData = """
            <augments>
              <record>
                <uid>Default</uid>
                <enable>true</enable>
                <enable-calendar>true</enable-calendar>
                <enable-addressbook>true</enable-addressbook>
              </record>
            </augments>
        """
        augments = FilePath(self.mktemp())
        augments.setContent(augmentsData)

        accountsData = """
            <accounts realm="Test Realm">
                <user>
                    <uid>user-under-test</uid>
                    <guid>user02</guid>
                    <name>Not Interesting</name>
                    <password>very-secret</password>
                </user>
            </accounts>
        """
        accounts = FilePath(self.mktemp())
        accounts.setContent(accountsData)
        output = FilePath(self.mktemp())
        self.accountsFile = accounts.path
        self.augmentsFile = augments.path
        main(['calendarserver_export', '--output',
              output.path, '--user', 'user-under-test'], reactor=self)

        yield self.waitToStop

        self.assertEquals(
            Component.fromString(resultForUser2),
            Component.fromString(output.getContent())
        )
    def setUp(self):
        """
        Set up two stores to migrate between.
        """
        # Add some files to the file store.

        self.filesPath = CachingFilePath(self.mktemp())
        self.filesPath.createDirectory()
        fileStore = self.fileStore = CommonDataStore(
            self.filesPath, StubNotifierFactory(), True, True
        )
        self.sqlStore = yield theStoreBuilder.buildStore(
            self, StubNotifierFactory()
        )
        subStarted = self.subStarted = Deferred()
        class StubService(Service, object):
            def startService(self):
                super(StubService, self).startService()
                if not subStarted.called:
                    subStarted.callback(None)
        from twisted.python import log
        def justOnce(evt):
            if evt.get('isError') and not hasattr(subStarted, 'result'):
                subStarted.errback(
                    evt.get('failure',
                            RuntimeError("error starting up (see log)"))
                )
        log.addObserver(justOnce)
        def cleanObserver():
            try:
                log.removeObserver(justOnce)
            except ValueError:
                pass # x not in list, I don't care.
        self.addCleanup(cleanObserver)
        self.stubService = StubService()
        self.topService = MultiService()
        self.upgrader = self.createUpgradeService()
        self.upgrader.setServiceParent(self.topService)

        requirements = CommonTests.requirements
        extras = deriveValue(self, "extraRequirements", lambda t: {})
        requirements = self.mergeRequirements(requirements, extras)

        yield populateCalendarsFrom(requirements, fileStore)
        md5s = CommonTests.md5s
        yield resetCalendarMD5s(md5s, fileStore)
        self.filesPath.child("calendars").child(
            "__uids__").child("ho").child("me").child("home1").child(
            ".some-extra-data").setContent("some extra data")

        requirements = ABCommonTests.requirements
        yield populateAddressBooksFrom(requirements, fileStore)
        md5s = ABCommonTests.md5s
        yield resetAddressBookMD5s(md5s, fileStore)
        self.filesPath.child("addressbooks").child(
            "__uids__").child("ho").child("me").child("home1").child(
            ".some-extra-data").setContent("some extra data")
    def populate(self):
        yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
        self.notifierFactory.reset()

        txn = self._sqlCalendarStore.newTransaction()
        Delete(
            From=schema.ATTACHMENT,
            Where=None
        ).on(txn)

        (yield txn.commit())
    def populate(self):
        yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
        self.notifierFactory.reset()

        txn = self._sqlCalendarStore.newTransaction()
        Delete(
            From=schema.ATTACHMENT,
            Where=None
        ).on(txn)

        (yield txn.commit())
示例#17
0
 def test_mailto(self):
     """
     Verify the conversion of non-mailto: CUAs to mailto: CUAs
     """
     yield populateCalendarsFrom(
         {"user01": {
             "calendar1": {
                 "peruser.ics": (dataWithUIDs, {}),
             }
         }}, self.store)
     io = StringIO()
     yield exportToFile([(yield self.txn().calendarHomeWithUID("user01")
                          ).calendarWithName("calendar1")],
                        io,
                        convertToMailto=True)
     self.assertEquals(Component.fromString(resultWithMailtos),
                       Component.fromString(io.getvalue()))
示例#18
0
    def test_onlyOneVTIMEZONE(self):
        """
        C{VTIMEZONE} subcomponents with matching TZIDs in multiple event
        calendar objects should only be rendered in the resulting output once.

        (Note that the code to suppor this is actually in PyCalendar, not the
        export tool itself.)
        """
        yield populateCalendarsFrom(
            {
                "user01": {
                    "calendar1": {
                        "1.ics": (one, {}),  # EST
                        "2.ics": (another, {}),  # EST
                        "3.ics": (third, {})  # PST
                    }
                }
            }, self.store
        )

        io = StringIO()
        yield exportToFile(
            [(yield self.txn().calendarHomeWithUID("user01"))
                .calendarWithName("calendar1")], io
        )
        result = Component.fromString(io.getvalue())

        def filtered(name):
            for c in result.subcomponents():
                if c.name() == name:
                    yield c

        timezones = list(filtered("VTIMEZONE"))
        events = list(filtered("VEVENT"))

        # Sanity check to make sure we picked up all three events:
        self.assertEquals(len(events), 3)

        self.assertEquals(len(timezones), 2)
        self.assertEquals(set([tz.propertyValue("TZID") for tz in timezones]),

                          # Use an intentionally wrong TZID in order to make
                          # sure we don't depend on caching effects elsewhere.
                          set(["America/New_Yrok", "US/Pacific"]))
示例#19
0
    def test_onlyOneVTIMEZONE(self):
        """
        C{VTIMEZONE} subcomponents with matching TZIDs in multiple event
        calendar objects should only be rendered in the resulting output once.

        (Note that the code to suppor this is actually in PyCalendar, not the
        export tool itself.)
        """
        yield populateCalendarsFrom(
            {
                "home1": {
                    "calendar1": {
                        "1.ics": (one, {}), # EST
                        "2.ics": (another, {}), # EST
                        "3.ics": (third, {}) # PST
                    }
                }
            }, self.store
        )

        io = StringIO()
        yield exportToFile(
            [(yield self.txn().calendarHomeWithUID("home1"))
              .calendarWithName("calendar1")], io
        )
        result = Component.fromString(io.getvalue())

        def filtered(name):
            for c in result.subcomponents():
                if c.name() == name:
                    yield c

        timezones = list(filtered("VTIMEZONE"))
        events = list(filtered("VEVENT"))

        # Sanity check to make sure we picked up all three events:
        self.assertEquals(len(events), 3)

        self.assertEquals(len(timezones), 2)
        self.assertEquals(set([tz.propertyValue("TZID") for tz in timezones]),

                          # Use an intentionally wrong TZID in order to make
                          # sure we don't depend on caching effects elsewhere.
                          set(["America/New_Yrok", "US/Pacific"]))
示例#20
0
 def test_perUserFiltering(self):
     """
     L{exportToFile} performs per-user component filtering based on the owner
     of that calendar.
     """
     yield populateCalendarsFrom(
         {
             "user02": {
                 "calendar1": {
                     "peruser.ics": (dataForTwoUsers, {}),  # EST
                 }
             }
         },
         self.store)
     io = StringIO()
     yield exportToFile([(yield self.txn().calendarHomeWithUID("user02")
                          ).calendarWithName("calendar1")], io)
     self.assertEquals(Component.fromString(resultForUser2),
                       Component.fromString(io.getvalue()))
示例#21
0
 def test_migrateMergeDontDeleteDefault(self):
     """
     If we're doing a merge migration, it's quite possible that the user has
     scheduled events onto their default calendar already.  In fact the
     whole point of a merge migration is to preserve data that might have
     been created there.  So, let's make sure that we I{don't} delete any
     data from the default calendars in the case that we're merging.
     """
     yield populateCalendarsFrom(
         {
             "empty_home": {
                 # see test_migrateEmptyHome above.
                 "other-default-calendar": {}
             },
             "non_empty_home": {
                 "calendar": {
                     "some-name": self.sampleEvent("some-uid",
                                                   "some summary"),
                 },
                 "inbox": {},
                 "tasks": {}
             }
         },
         self.storeUnderTest())
     txn = self.transactionUnderTest()
     emptyHome = yield txn.calendarHomeWithUID("empty_home")
     self.assertIdentical((yield emptyHome.calendarWithName("calendar")),
                          None)
     nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")
     yield migrateHome(emptyHome, nonEmpty, merge=True)
     yield self.commit()
     txn = self.transactionUnderTest()
     emptyHome = yield txn.calendarHomeWithUID("empty_home")
     nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")
     self.assertNotIdentical((yield nonEmpty.calendarWithName("inbox")),
                             None)
     defaultCal = (yield nonEmpty.calendarWithName("calendar"))
     self.assertNotIdentical(
         (yield defaultCal.calendarObjectWithName("some-name")), None)
示例#22
0
 def test_perUserFiltering(self):
     """
     L{exportToFile} performs per-user component filtering based on the owner
     of that calendar.
     """
     yield populateCalendarsFrom(
         {
             "user02": {
                 "calendar1": {
                     "peruser.ics": (dataForTwoUsers, {}), # EST
                 }
             }
         }, self.store
     )
     io = StringIO()
     yield exportToFile(
         [(yield self.txn().calendarHomeWithUID("user02"))
           .calendarWithName("calendar1")], io
     )
     self.assertEquals(
         Component.fromString(resultForUser2),
         Component.fromString(io.getvalue())
     )
    def populate(self):
        populateTxn = self.storeUnderTest().newTransaction()
        addressookRequirements = self.requirements["addressbook"]
        for homeUID in addressookRequirements:
            addressbooks = addressookRequirements[homeUID]
            if addressbooks is not None:
                home = yield populateTxn.addressbookHomeWithUID(homeUID, True)
                addressbook = home.addressbook()

                addressbookObjNames = addressbooks[addressbook.name()]
                if addressbookObjNames is not None:
                    for objectName in addressbookObjNames:
                        objData = addressbookObjNames[objectName]
                        yield addressbook.createAddressBookObjectWithName(
                            objectName, VCard.fromString(objData)
                        )

        yield populateTxn.commit()

        calendarRequirements = self.requirements["calendar"]
        yield populateCalendarsFrom(calendarRequirements, self.storeUnderTest())

        self.notifierFactory.reset()
示例#24
0
    def createConflicted(self, c1=None, c2=None):
        """
        Create two calendar homes with calendars with the same names within
        them.  Parameters are both a mapping of calendar object names to
        2-tuples of (iCalendar data, metadata).

        @param c1: the calendar data for conflict1/conflicted/*

        @param c2: the calendar data for conflict2/conflicted/*
        """
        if c1 is None:
            c1 = {"1.ics": self.sampleEvent("uid1")}
        if c2 is None:
            c2 = {"2.ics": self.sampleEvent("uid2")}
        defaults = {"calendar": {}, "inbox": {}, "tasks": {}, "polls": {}}
        def conflicted(caldata):
            d = defaults.copy()
            d.update(conflicted=caldata)
            return d
        yield populateCalendarsFrom({
            "conflict1": conflicted(c1),
            "conflict2": conflicted(c2),
        }, self.storeUnderTest())
    def populate(self):
        populateTxn = self.storeUnderTest().newTransaction()
        addressookRequirements = self.requirements["addressbook"]
        for homeUID in addressookRequirements:
            addressbooks = addressookRequirements[homeUID]
            if addressbooks is not None:
                home = yield populateTxn.addressbookHomeWithUID(homeUID, True)
                addressbook = home.addressbook()

                addressbookObjNames = addressbooks[addressbook.name()]
                if addressbookObjNames is not None:
                    for objectName in addressbookObjNames:
                        objData = addressbookObjNames[objectName]
                        yield addressbook.createAddressBookObjectWithName(
                            objectName, VCard.fromString(objData))

        yield populateTxn.commit()

        calendarRequirements = self.requirements["calendar"]
        yield populateCalendarsFrom(calendarRequirements,
                                    self.storeUnderTest())

        self.notifierFactory.reset()
示例#26
0
 def test_migrateMergeDontDeleteDefault(self):
     """
     If we're doing a merge migration, it's quite possible that the user has
     scheduled events onto their default calendar already.  In fact the
     whole point of a merge migration is to preserve data that might have
     been created there.  So, let's make sure that we I{don't} delete any
     data from the default calendars in the case that we're merging.
     """
     yield populateCalendarsFrom({
         "empty_home": {
             # see test_migrateEmptyHome above.
             "other-default-calendar": {}
         },
         "non_empty_home": {
             "calendar": {
                 "some-name": self.sampleEvent("some-uid", "some summary"),
             }, "inbox": {}, "tasks": {}
         }
     }, self.storeUnderTest())
     txn = self.transactionUnderTest()
     emptyHome = yield txn.calendarHomeWithUID("empty_home")
     self.assertIdentical((yield emptyHome.calendarWithName("calendar")),
                          None)
     nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")
     yield migrateHome(emptyHome, nonEmpty, merge=True)
     yield self.commit()
     txn = self.transactionUnderTest()
     emptyHome = yield txn.calendarHomeWithUID("empty_home")
     nonEmpty = yield txn.calendarHomeWithUID("non_empty_home")
     self.assertNotIdentical(
         (yield nonEmpty.calendarWithName("inbox")), None
     )
     defaultCal = (yield nonEmpty.calendarWithName("calendar"))
     self.assertNotIdentical(
         (yield defaultCal.calendarObjectWithName("some-name")), None
     )
示例#27
0
 def populate(self):
     yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
     self.notifierFactory.reset()
示例#28
0
 def populate(self):
     yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
     yield populateAddressBooksFrom(self.requirements, self.storeUnderTest())
    def populate(self):

        # Need to bypass normal validation inside the store
        yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
        self.notifierFactory.reset()
示例#30
0
 def populate(self):
     yield populateCalendarsFrom(self.requirements0, self.theStoreUnderTest(0))
     yield populateCalendarsFrom(self.requirements1, self.theStoreUnderTest(1))
示例#31
0
 def populate(self):
     yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
     self.notifierFactory.reset()
示例#32
0
    def test_full(self):
        """
        Running C{calendarserver_export} on the command line exports an ics
        file. (Almost-full integration test, starting from the main point, using
        as few test fakes as possible.)

        Note: currently the only test for directory interaction.
        """
        yield populateCalendarsFrom(
            {
                "user02": {
                    # TODO: more direct test for skipping inbox
                    "inbox": {
                        "inbox-item.ics": (valentines, {})
                    },
                    "calendar1": {
                        "peruser.ics": (dataForTwoUsers, {}),  # EST
                    }
                }
            },
            self.store)

        output = FilePath(self.mktemp())
        main([
            'calendarserver_export', '--output', output.path, '--user',
            'user02'
        ],
             reactor=self)

        yield self.waitToStop

        self.assertEquals(Component.fromString(resultForUser2),
                          Component.fromString(output.getContent()))

        @inlineCallbacks
        def test_exportAll(self):
            """
            Run the export with --all to get a directory of calendars from all
            calendar homes in the database.
            """
            yield populateCalendarsFrom(
                {
                    "user01": {
                        "calendar1": {
                            "valentines-day.ics": (valentines, {}),
                            "new-years-day.ics": (newYears, {})
                        }
                    },
                    "user02": {
                        "calendar1": {
                            "valentines-day.ics": (valentines, {})
                        },
                        "calendar2": {
                            "new-years-day.ics": (newYears, {})
                        }
                    }
                }, self.store)

            outputDir = FilePath(self.mktemp())
            outputDir.makedirs()
            main([
                'calendarserver_export', '--directory', outputDir.path, '--all'
            ],
                 reactor=self)
            yield self.waitToStop
            self.assertEquals(
                set([
                    "user01_calendar1.ics", "user02_calendar1.ics",
                    "user02_calendar2.ics"
                ]), set([child.basename() for child in outputDir.children()]))
示例#33
0
    def test_exportMixAndMatch(self):
        """
        Run the export with some calendars and some addressbooks
        """
        yield populateAddressBooksFrom(
            {
                "user01": {
                    "addressbook": {
                        "1.vcf": adbk1Root.child("1.vcf").getContent(),
                        "2.vcf": adbk1Root.child("2.vcf").getContent(),
                        "3.vcf": adbk1Root.child("3.vcf").getContent(),
                    }
                },
                "user02": {
                    "addressbook": {
                        "1.vcf": adbk1Root.child("1.vcf").getContent(),
                    },
                }
            }, self.store)
        yield populateCalendarsFrom(
            {
                "user01": {
                    "calendar1": {
                        "valentines-day.ics": (valentines, {}),
                        "new-years-day.ics": (newYears, {})
                    }
                },
                "user02": {
                    "calendar1": {
                        "valentines-day.ics": (valentines, {})
                    },
                    "calendar2": {
                        "new-years-day.ics": (newYears, {})
                    }
                }
            }, self.store)

        outputDir = FilePath(self.mktemp())
        outputDir.makedirs()
        main([
            'calendarserver_export',
            '--directory',
            outputDir.path,
            '--uid',
            'user01',
            '--contacts',
            '--uid',
            'user01',
            '--calendars',
            '--uid',
            'user02',
            '--collection=calendar1',
            '--uid',
            'user02',
            '--contacts',
        ],
             reactor=self)
        yield self.waitToStop
        self.assertEquals(
            set([
                "user01_addressbook.vcf", "user01_calendar1.ics",
                "user02_calendar1.ics", "user02_addressbook.vcf"
            ]), set([child.basename() for child in outputDir.children()]))
示例#34
0
 def populate(self):
     yield populateCalendarsFrom(self.requirements0,
                                 self.theStoreUnderTest(0))
     yield populateCalendarsFrom(self.requirements1,
                                 self.theStoreUnderTest(1))
示例#35
0
 def populate(self):
     yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
     yield populateAddressBooksFrom(self.requirements,
                                    self.storeUnderTest())
示例#36
0
    def populate(self):

        # Need to bypass normal validation inside the store
        yield populateCalendarsFrom(self.requirements, self.storeUnderTest())
        self.notifierFactory.reset()
示例#37
0
    def setUp(self):
        """
        Set up two stores to migrate between.
        """

        yield super(HomeMigrationTests, self).setUp()
        yield self.buildStoreAndDirectory(extraUids=(
            u"home1",
            u"home2",
            u"home3",
            u"home_defaults",
            u"home_no_splits",
            u"home_splits",
            u"home_splits_shared",
        ))
        self.sqlStore = self.store

        # Add some files to the file store.

        self.filesPath = CachingFilePath(self.mktemp())
        self.filesPath.createDirectory()
        fileStore = self.fileStore = CommonDataStore(
            self.filesPath, {"push": StubNotifierFactory()}, self.directory,
            True, True)
        self.upgrader = UpgradeToDatabaseStep(self.fileStore, self.sqlStore)

        requirements = CommonTests.requirements
        extras = deriveValue(self, "extraRequirements", lambda t: {})
        requirements = self.mergeRequirements(requirements, extras)

        yield populateCalendarsFrom(requirements, fileStore)
        md5s = CommonTests.md5s
        yield resetCalendarMD5s(md5s, fileStore)
        self.filesPath.child("calendars").child("__uids__").child("ho").child(
            "me").child("home1").child(".some-extra-data").setContent(
                "some extra data")

        requirements = ABCommonTests.requirements
        yield populateAddressBooksFrom(requirements, fileStore)
        md5s = ABCommonTests.md5s
        yield resetAddressBookMD5s(md5s, fileStore)
        self.filesPath.child("addressbooks").child("__uids__").child(
            "ho").child("me").child("home1").child(
                ".some-extra-data").setContent("some extra data")

        # Add some properties we want to check get migrated over
        txn = self.fileStore.newTransaction()
        home = yield txn.calendarHomeWithUID("home_defaults")

        cal = yield home.calendarWithName("calendar_1")
        props = cal.properties()
        props[PropertyName.fromElement(
            caldavxml.SupportedCalendarComponentSet
        )] = caldavxml.SupportedCalendarComponentSet(
            caldavxml.CalendarComponent(name="VEVENT"),
            caldavxml.CalendarComponent(name="VTODO"),
        )
        props[PropertyName.fromElement(
            element.ResourceType)] = element.ResourceType(
                element.Collection(),
                caldavxml.Calendar(),
            )
        props[PropertyName.fromElement(
            customxml.GETCTag)] = customxml.GETCTag.fromString("foobar")

        inbox = yield home.calendarWithName("inbox")
        props = inbox.properties()
        props[PropertyName.fromElement(
            customxml.CalendarAvailability
        )] = customxml.CalendarAvailability.fromString(str(self.av1))
        props[PropertyName.fromElement(
            caldavxml.ScheduleDefaultCalendarURL
        )] = caldavxml.ScheduleDefaultCalendarURL(
            element.HRef.fromString(
                "/calendars/__uids__/home_defaults/calendar_1"), )

        yield txn.commit()