mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2025-01-03 02:28:53 +00:00
Complete javascript testing of password functionality
* And fix bugs, nullable collection_path
This commit is contained in:
parent
e202ac9d19
commit
2bc2140d43
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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___ */
|
||||
|
@ -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
|
||||
|
14
library/tests/test-javascript.js
Normal file
14
library/tests/test-javascript.js
Normal 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();
|
52
library/tests/test-lookup-password.js
Normal file
52
library/tests/test-lookup-password.js
Normal 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();
|
68
library/tests/test-remove-password.js
Normal file
68
library/tests/test-remove-password.js
Normal 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();
|
58
library/tests/test-store-password.js
Normal file
58
library/tests/test-store-password.js
Normal 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();
|
Loading…
Reference in New Issue
Block a user