Skip to content

Commit

Permalink
Expose base file path and base uri on App
Browse files Browse the repository at this point in the history
  • Loading branch information
nirinchev committed Jul 20, 2023
1 parent 6195bdc commit 37be26f
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 2 deletions.
22 changes: 22 additions & 0 deletions Realm/Realm/Handles/AppHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ public static extern IntPtr get_user_for_testing(
[DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_app_clear_cached_apps", CallingConvention = CallingConvention.Cdecl)]
public static extern void clear_cached_apps(out NativeException ex);

[DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_app_get_base_file_path", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr get_base_file_path(AppHandle app, IntPtr buffer, IntPtr buffer_length, out NativeException ex);

[DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_app_get_base_uri", CallingConvention = CallingConvention.Cdecl)]
public static extern StringValue get_base_uri(AppHandle app, out NativeException ex);

public static class EmailPassword
{
[DllImport(InteropConfig.DLL_NAME, EntryPoint = "shared_app_email_register_user", CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -349,6 +355,22 @@ public SyncUserHandle GetUserForTesting(string id, string refreshToken, string a
return new SyncUserHandle(result);
}

public string GetBaseFilePath()
{
return MarshalHelpers.GetString((IntPtr buffer, IntPtr length, out bool isNull, out NativeException ex) =>
{
isNull = false;
return NativeMethods.get_base_file_path(this, buffer, length, out ex);
})!;
}

public Uri GetBaseUri()
{
var value = NativeMethods.get_base_uri(this, out var ex);
ex.ThrowIfNecessary();
return new Uri(value!);
}

protected override void Unbind() => NativeMethods.destroy(handle);

[MonoPInvokeCallback(typeof(NativeMethods.UserCallback))]
Expand Down
16 changes: 15 additions & 1 deletion Realm/Realm/Sync/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,21 @@ public class App
.Select(handle => new User(handle, this))
.ToArray();

/// <summary>
/// Gets the root folder relative to which all local data for this application will be stored. This data includes
/// metadata for users and synchronized Realms.
/// </summary>
/// <value>The app's base path.</value>
/// <seealso cref="AppConfiguration.BaseFilePath"/>
public string BaseFilePath => Handle.GetBaseFilePath();

/// <summary>
/// Gets the base url for this Realm application.
/// </summary>
/// <value>The app's base url.</value>
/// <seealso cref="AppConfiguration.BaseUri"/>
public Uri BaseUri => Handle.GetBaseUri();

internal App(AppHandle handle)
{
Handle = handle;
Expand All @@ -129,7 +144,6 @@ internal App(AppHandle handle)
/// </summary>
/// <param name="config">The <see cref="AppConfiguration"/>, specifying key parameters for the app behavior.</param>
/// <returns>An <see cref="App"/> instance can now be used to login users, call functions, or open synchronized Realms.</returns>
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The http client is owned by the app and must be kept alive.")]
public static App Create(AppConfiguration config)
{
Argument.NotNull(config, nameof(config));
Expand Down
8 changes: 7 additions & 1 deletion Tests/Realm.Tests/Sync/AppTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
Expand Down Expand Up @@ -127,6 +128,9 @@ void AssertBundleId(params string[] expectedValues)
[Test]
public void AppCreate_CreatesApp()
{
var basePath = Path.Combine(InteropConfig.GetDefaultStorageFolder("No error expected here"), "foo-bar");
Directory.CreateDirectory(basePath);

// This is mostly a smoke test to ensure that nothing blows up when setting all properties.
var config = new AppConfiguration("abc-123")
{
Expand All @@ -135,12 +139,14 @@ public void AppCreate_CreatesApp()
LocalAppVersion = "1.2.3",
MetadataEncryptionKey = new byte[64],
MetadataPersistenceMode = MetadataPersistenceMode.Encrypted,
BaseFilePath = InteropConfig.GetDefaultStorageFolder("No error expected here"),
BaseFilePath = basePath,
DefaultRequestTimeout = TimeSpan.FromSeconds(123)
};

var app = CreateApp(config);
Assert.That(app.Sync, Is.Not.Null);
Assert.That(app.BaseUri, Is.EqualTo(config.BaseUri));
Assert.That(app.BaseFilePath, Is.EqualTo(config.BaseFilePath));
}

[Test]
Expand Down
22 changes: 22 additions & 0 deletions Tests/Realm.Tests/Sync/SessionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,28 @@ public void Session_PermissionDenied_DoesntCrash()
}, timeout: 1000000);
}

[Test]
public void Session_GetUser_GetApp_ReturnsMeaningfulValue()
{
// Session.User.App doesn't have a reference to the managed app, which means we need to
// recreate it from the native one. This test verifies that the properties on the native
// app match the ones on the managed one.
var fakeConfig = new Realms.Sync.AppConfiguration("foo-bar")
{
BaseUri = new Uri("http://localhost:12345"),
BaseFilePath = Path.Combine(InteropConfig.GetDefaultStorageFolder("no error expected"), Guid.NewGuid().ToString())
};
Directory.CreateDirectory(fakeConfig.BaseFilePath);

var fakeApp = CreateApp(fakeConfig);

var realm = GetRealm(GetFakeConfig(fakeApp));
var session = GetSession(realm);

Assert.That(session.User.App.BaseFilePath, Is.EqualTo(fakeConfig.BaseFilePath));
Assert.That(session.User.App.BaseUri, Is.EqualTo(fakeConfig.BaseUri));
}

private static ClientResetHandlerBase GetClientResetHandler(
Type type,
BeforeResetCallback? beforeCb = null,
Expand Down
15 changes: 15 additions & 0 deletions wrappers/src/app_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,21 @@ extern "C" {
App::clear_cached_apps();
}

REALM_EXPORT size_t shared_app_get_base_file_path(SharedApp& app, uint16_t* buffer, size_t buffer_length, NativeException::Marshallable& ex)
{
return handle_errors(ex, [&]() {
std::string base_file_path(app->sync_manager()->config().base_file_path);
return stringdata_to_csharpstringbuffer(base_file_path, buffer, buffer_length);
});
}

REALM_EXPORT realm_string_t shared_app_get_base_uri(SharedApp& app, uint16_t* buffer, size_t buffer_length, NativeException::Marshallable& ex)
{
return handle_errors(ex, [&]() {
return to_capi(app->base_url());
});
}

#pragma region EmailPassword

REALM_EXPORT void shared_app_email_register_user(SharedApp& app, uint16_t* username_buf, size_t username_len, uint16_t* password_buf, size_t password_len, void* tcs_ptr, NativeException::Marshallable& ex)
Expand Down

0 comments on commit 37be26f

Please sign in to comment.