Complete javascript testing of password functionality

* And fix bugs, nullable collection_path
This commit is contained in:
Stef Walter 2012-03-11 13:35:43 +01:00
parent e202ac9d19
commit 2bc2140d43
9 changed files with 266 additions and 26 deletions

2
.gitignore vendored
View File

@ -65,4 +65,6 @@ stamp*
/library/secret-enum-types.[ch]
/library/tests/test-*
!/library/tests/test-*.c
!/library/tests/test-*.js
!/library/tests/test-*.py

View File

@ -1659,7 +1659,7 @@ secret_service_unlock_sync (SecretService *self,
* secret_service_store:
* @self: the secret service
* @schema: the schema to for attributes
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@ -1677,6 +1677,10 @@ secret_service_unlock_sync (SecretService *self,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is not specified, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method will return immediately and complete asynchronously.
*/
void
@ -1695,7 +1699,6 @@ secret_service_store (SecretService *self,
g_return_if_fail (SECRET_IS_SERVICE (self));
g_return_if_fail (schema != NULL);
g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (value != NULL);
@ -1714,7 +1717,7 @@ secret_service_store (SecretService *self,
* @self: the secret service
* @schema: the schema to for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@ -1728,6 +1731,10 @@ secret_service_store (SecretService *self,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is not specified, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method will return immediately and complete asynchronously.
*/
void
@ -1747,7 +1754,6 @@ secret_service_storev (SecretService *self,
g_return_if_fail (SECRET_IS_SERVICE (self));
g_return_if_fail (schema != NULL);
g_return_if_fail (attributes != NULL);
g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (value != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@ -1810,7 +1816,7 @@ secret_service_store_finish (SecretService *self,
* secret_service_store_sync:
* @self: the secret service
* @schema: the schema to for attributes
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@ -1827,6 +1833,10 @@ secret_service_store_finish (SecretService *self,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method may block indefinitely and should not be used in user interface
* threads.
*
@ -1848,7 +1858,6 @@ secret_service_store_sync (SecretService *self,
g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (schema != NULL, FALSE);
g_return_val_if_fail (collection_path != NULL, FALSE);
g_return_val_if_fail (label != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
@ -1871,7 +1880,7 @@ secret_service_store_sync (SecretService *self,
* @self: the secret service
* @schema: the schema to for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@ -1884,6 +1893,10 @@ secret_service_store_sync (SecretService *self,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method may block indefinitely and should not be used in user interface
* threads.
*
@ -1905,7 +1918,6 @@ secret_service_storev_sync (SecretService *self,
g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (schema != NULL, FALSE);
g_return_val_if_fail (attributes != NULL, FALSE);
g_return_val_if_fail (collection_path != NULL, FALSE);
g_return_val_if_fail (label != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
@ -3137,7 +3149,7 @@ on_create_item_session (GObject *source,
/**
* secret_service_create_item_path:
* @self: a secret service object
* @collection_path: dbus path to collection in which to create item
* @collection_path: (allow-none): dbus path to collection in which to create item
* @properties: hash table of properties for the new collection
* @value: the secret value to store in the item
* @replace: whether to replace an item with the matching attributes
@ -3159,6 +3171,10 @@ on_create_item_session (GObject *source,
* <literal>org.freedesktop.Secret.Item.Label</literal>. The values
* in the hash table should be #GVariant values of the properties.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method will return immediately and complete asynchronously. The secret
* service may prompt the user. secret_service_prompt() will be used to handle
* any prompts that are required.
@ -3181,6 +3197,9 @@ secret_service_create_item_path (SecretService *self,
g_return_if_fail (value != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
if (collection_path == NULL)
collection_path = SECRET_COLLECTION_DEFAULT;
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
secret_service_create_item_path);
closure = g_slice_new0 (ItemClosure);
@ -3238,7 +3257,7 @@ secret_service_create_item_path_finish (SecretService *self,
/**
* secret_service_create_item_path_sync:
* @self: a secret service object
* @collection_path: dbus path to collection in which to create item
* @collection_path: (allow-none): dbus path to collection in which to create item
* @properties: hash table of properties for the new collection
* @value: the secret value to store in the item
* @replace: whether to replace an item with the matching attributes

View File

@ -110,7 +110,7 @@ on_store_connected (GObject *source,
/**
* secret_password_store:
* @schema: the schema for attributes
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@ -128,6 +128,10 @@ on_store_connected (GObject *source,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method will return immediately and complete asynchronously.
*/
void
@ -144,7 +148,6 @@ secret_password_store (const SecretSchema *schema,
va_list va;
g_return_if_fail (schema != NULL);
g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (password != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@ -163,7 +166,7 @@ secret_password_store (const SecretSchema *schema,
* secret_password_storev:
* @schema: the schema for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@ -177,6 +180,10 @@ secret_password_store (const SecretSchema *schema,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method will return immediately and complete asynchronously.
*
* Rename to: secret_password_store
@ -195,7 +202,6 @@ secret_password_storev (const SecretSchema *schema,
StoreClosure *closure;
g_return_if_fail (schema != NULL);
g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (password != NULL);
g_return_if_fail (attributes != NULL);
@ -254,7 +260,7 @@ secret_password_store_finish (GAsyncResult *result,
/**
* secret_password_store_sync:
* @schema: the schema for attributes
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@ -271,6 +277,10 @@ secret_password_store_finish (GAsyncResult *result,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method may block indefinitely and should not be used in user interface
* threads.
*
@ -310,7 +320,7 @@ secret_password_store_sync (const SecretSchema *schema,
* secret_password_storev_sync:
* @schema: the schema for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
* @collection_path: the dbus path to the collection where to store the secret
* @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@ -323,6 +333,10 @@ secret_password_store_sync (const SecretSchema *schema,
* If the attributes match a secret item already stored in the collection, then
* the item will be updated with these new values.
*
* If @collection_path is %NULL, then the default collection will be
* used. Use #SECRET_COLLECTION_SESSION to store the password in the session
* collection, which doesn't get stored across login sessions.
*
* This method may block indefinitely and should not be used in user interface
* threads.
*
@ -343,7 +357,6 @@ secret_password_storev_sync (const SecretSchema *schema,
gboolean ret;
g_return_val_if_fail (schema != NULL, FALSE);
g_return_val_if_fail (collection_path != NULL, FALSE);
g_return_val_if_fail (label != NULL, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (attributes != NULL, FALSE);

View File

@ -35,6 +35,10 @@ typedef struct _SecretPrompt SecretPrompt;
typedef struct _SecretService SecretService;
typedef struct _SecretValue SecretValue;
#define SECRET_COLLECTION_DEFAULT "/org/freedesktop/secrets/aliases/default"
#define SECRET_COLLECTION_SESSION "/org/freedesktop/secrets/aliases/session"
G_END_DECLS
#endif /* __G_SERVICE_H___ */

View File

@ -56,12 +56,22 @@ EXTRA_DIST = \
mock-service-prompt.py \
$(NULL)
test: $(TEST_PROGS)
gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
JS_TESTS = \
test-lookup-password.js \
test-remove-password.js \
test-store-password.js
test-javascript:
LD_LIBRARY_PATH=$(builddir)/.libs GI_TYPELIB_PATH=$(builddir)/..:$(builddir) \
gjs test-lookup-password.js
JS_ENV = \
LD_LIBRARY_PATH=$(builddir)/.libs \
GI_TYPELIB_PATH=$(builddir)/..:$(builddir)
test: test-c test-js
test-c: $(TEST_PROGS)
@gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
test-js:
@for js in $(JS_TESTS); do echo "TEST: $$js"; $(JS_ENV) gjs $$js; done
# ------------------------------------------------------------------
# INTROSPECTION

View File

@ -0,0 +1,14 @@
const Mock = imports.gi.MockService;
const Secret = imports.gi.Secret;
Mock.start("mock-service-normal.py");
var schema = new Secret.Schema.new("org.test",
Secret.SchemaFlags.NONE,
{ "blah": Secret.SchemaAttributeType.STRING });
log(schema.identifier);
log(schema.flags);
/* log(schema.attributes); */
Mock.stop();

View File

@ -0,0 +1,52 @@
const Mock = imports.gi.MockService;
const Secret = imports.gi.Secret;
const GLib = imports.gi.GLib;
const JsUnit = imports.jsUnit;
const assertEquals = JsUnit.assertEquals;
const assertRaises = JsUnit.assertRaises;
const assertTrue = JsUnit.assertTrue;
Mock.start("mock-service-normal.py");
const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store",
Secret.SchemaFlags.NONE,
{
"number": Secret.SchemaAttributeType.INTEGER,
"string": Secret.SchemaAttributeType.STRING,
"even": Secret.SchemaAttributeType.BOOLEAN,
}
);
/* Synchronous */
var password = Secret.password_lookup_sync (STORE_SCHEMA, { "number": "1", "even": "false" }, null);
assertEquals("111", password);
var password = Secret.password_lookup_sync (STORE_SCHEMA, { "number": "5", "even": "true" }, null);
assertEquals(null, password);
/* Asynchronous */
var loop = new GLib.MainLoop.new(null, false);
Secret.password_lookup (STORE_SCHEMA, { "number": "2", "string": "two" },
null, function(source, result) {
loop.quit();
var password = Secret.password_lookup_finish(result);
assertEquals("222", password);
});
loop.run();
Secret.password_lookup (STORE_SCHEMA, { "number": "7", "string": "five" },
null, function(source, result) {
loop.quit();
var password = Secret.password_lookup_finish(result);
assertEquals(null, password);
});
loop.run();
Mock.stop();

View File

@ -0,0 +1,68 @@
const Mock = imports.gi.MockService;
const Secret = imports.gi.Secret;
const GLib = imports.gi.GLib;
const JsUnit = imports.jsUnit;
const assertEquals = JsUnit.assertEquals;
const assertRaises = JsUnit.assertRaises;
const assertTrue = JsUnit.assertTrue;
Mock.start("mock-service-normal.py");
const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store",
Secret.SchemaFlags.NONE,
{
"number": Secret.SchemaAttributeType.INTEGER,
"string": Secret.SchemaAttributeType.STRING,
"even": Secret.SchemaAttributeType.BOOLEAN,
}
);
/* Synchronous */
var attributes = { "number": "1", "string": "one", "even": "false" };
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals("111", password);
var deleted = Secret.password_remove_sync (STORE_SCHEMA, attributes, null);
assertEquals(true, deleted);
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals(null, password);
var deleted = Secret.password_remove_sync (STORE_SCHEMA, attributes, null);
assertEquals(false, deleted);
/* Asynchronous */
var attributes = { "number": "2", "string": "two", "even": "true" };
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals("222", password);
var loop = new GLib.MainLoop.new(null, false);
Secret.password_remove (STORE_SCHEMA, attributes,
null, function(source, result) {
loop.quit();
var deleted = Secret.password_remove_finish(result);
assertEquals(true, deleted);
});
loop.run();
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals(null, password);
Secret.password_remove (STORE_SCHEMA, attributes,
null, function(source, result) {
loop.quit();
var deleted = Secret.password_remove_finish(result);
assertEquals(false, deleted);
});
loop.run();
Mock.stop();

View File

@ -0,0 +1,58 @@
const Mock = imports.gi.MockService;
const Secret = imports.gi.Secret;
const GLib = imports.gi.GLib;
const JsUnit = imports.jsUnit;
const assertEquals = JsUnit.assertEquals;
const assertRaises = JsUnit.assertRaises;
const assertTrue = JsUnit.assertTrue;
Mock.start("mock-service-normal.py");
const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store",
Secret.SchemaFlags.NONE,
{
"number": Secret.SchemaAttributeType.INTEGER,
"string": Secret.SchemaAttributeType.STRING,
"even": Secret.SchemaAttributeType.BOOLEAN,
}
);
/* Synchronous */
var attributes = { "number": "9", "string": "nine", "even": "false" };
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals(null, password);
var stored = Secret.password_store_sync (STORE_SCHEMA, attributes, Secret.COLLECTION_DEFAULT,
"The number nine", "999", null);
assertEquals(true, stored);
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals("999", password);
/* Asynchronous */
var attributes = { "number": "888", "string": "eight", "even": "true" };
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals(null, password);
var loop = new GLib.MainLoop.new(null, false);
Secret.password_store (STORE_SCHEMA, attributes, null, "The number eight", "888",
null, function(source, result) {
loop.quit();
var stored = Secret.password_store_finish(result);
assertEquals(true, stored);
});
loop.run();
var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
assertEquals("888", password);
Mock.stop();