D-Bus API: allow reading template for non-existent context (MB #10448)
A client which wants to create a new config in a non-default context should always use config = GetConfig("<template>@context", true) <make changes> SetConfig(config) to ensure that shared properties in that context are preserved. A client shouldn't have to check whether that context exists. If it doesn't, the server should simply ignore the context and use the default values from the template. This patch adds a test for this, based on the "type" property. The expectation in the test that the "type" is preserved literally is wrong. "type" currently must not be preserved, because different templates may have to set different data formats (MB #10443).
This commit is contained in:
parent
8a12b94684
commit
a3f4a06e95
|
@ -233,8 +233,14 @@ private:
|
|||
*/
|
||||
virtual bool setFilters(SyncConfig &config) { return false; }
|
||||
|
||||
/** utility method which constructs a SyncConfig which references a local configuration (never a template) */
|
||||
boost::shared_ptr<DBusUserInterface> getLocalConfig(const std::string &configName);
|
||||
/**
|
||||
* utility method which constructs a SyncConfig which references a local configuration (never a template)
|
||||
*
|
||||
* In general, the config must exist, except in two cases:
|
||||
* - configName = @default (considered always available)
|
||||
* - mustExist = false (used when reading a templates for a context which might not exist yet)
|
||||
*/
|
||||
boost::shared_ptr<DBusUserInterface> getLocalConfig(const std::string &configName, bool mustExist = true);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2365,7 +2371,7 @@ void ReadOperations::getConfigs(bool getTemplates, std::vector<std::string> &con
|
|||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<DBusUserInterface> ReadOperations::getLocalConfig(const string &configName)
|
||||
boost::shared_ptr<DBusUserInterface> ReadOperations::getLocalConfig(const string &configName, bool mustExist)
|
||||
{
|
||||
string peer, context;
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName),
|
||||
|
@ -2378,7 +2384,8 @@ boost::shared_ptr<DBusUserInterface> ReadOperations::getLocalConfig(const string
|
|||
// the default configuration can always be opened for reading,
|
||||
// everything else must exist
|
||||
if ((context != "default" || peer != "") &&
|
||||
!syncConfig->exists()) {
|
||||
mustExist &&
|
||||
!syncConfig->exists()) {
|
||||
SE_THROW_EXCEPTION(NoSuchConfig, "No configuration '" + configName + "' found");
|
||||
}
|
||||
}
|
||||
|
@ -2434,7 +2441,7 @@ void ReadOperations::getConfig(bool getTemplate,
|
|||
|
||||
// use the shared properties from the right context as filter
|
||||
// so that the returned template preserves existing properties
|
||||
boost::shared_ptr<DBusUserInterface> shared = getLocalConfig(string("@") + context);
|
||||
boost::shared_ptr<DBusUserInterface> shared = getLocalConfig(string("@") + context, false);
|
||||
|
||||
ConfigProps props;
|
||||
shared->getProperties()->readProperties(props);
|
||||
|
|
|
@ -2101,6 +2101,33 @@ class TestMultipleConfigs(unittest.TestCase, DBusUtil):
|
|||
config = self.server.GetConfig("@default", False, utf8_strings=True)
|
||||
self.failUnlessEqual(config["source/addressbook"]["type"], "file:text/x-vcard:2.1")
|
||||
|
||||
def testSharedTypeOther(self):
|
||||
"""'type' must not be overwritten when set in the context"""
|
||||
# writing for peer modifies "type" in "foo" and context "@other"
|
||||
self.setUpSession("Foo@other")
|
||||
config = self.server.GetConfig("ScheduleWorld@other", True, utf8_strings=True)
|
||||
config["source/addressbook"]["type"] = "file:text/vcard:3.0"
|
||||
self.session.SetConfig(False, False,
|
||||
config,
|
||||
utf8_strings=True)
|
||||
config = self.server.GetConfig("Foo", False, utf8_strings=True)
|
||||
self.failUnlessEqual(config["source/addressbook"]["type"], "file:text/vcard:3.0")
|
||||
config = self.server.GetConfig("@other", False, utf8_strings=True)
|
||||
self.failUnlessEqual(config["source/addressbook"]["type"], "file:text/vcard:3.0")
|
||||
self.session.Detach()
|
||||
|
||||
# adding second client must preserve type
|
||||
self.setUpSession("bar@other")
|
||||
config = self.server.GetConfig("Funambol@other", True, utf8_strings=True)
|
||||
self.failUnlessEqual(config["source/addressbook"]["type"], "file:text/vcard:3.0")
|
||||
self.session.SetConfig(False, False,
|
||||
config,
|
||||
utf8_strings=True)
|
||||
config = self.server.GetConfig("bar", False, utf8_strings=True)
|
||||
self.failUnlessEqual(config["source/addressbook"]["type"], "file:text/vcard:3.0")
|
||||
config = self.server.GetConfig("@other", False, utf8_strings=True)
|
||||
self.failUnlessEqual(config["source/addressbook"]["type"], "file:text/vcard:3.0")
|
||||
|
||||
def testOtherContext(self):
|
||||
"""write into independent context"""
|
||||
self.setupConfigs()
|
||||
|
|
Loading…
Reference in New Issue