Skip to content

Commit

Permalink
Fix for updated flexible sync error message (realm#4611)
Browse files Browse the repository at this point in the history
* Fix for updated flexible sync error message
* Upgrade to Realm Core v12.1.0

Co-authored-by: Kenneth Geisshirt <[email protected]>
Co-authored-by: Kræn Hansen <[email protected]>
  • Loading branch information
3 people committed Jun 2, 2022
1 parent eb6f1f7 commit 276c190
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 34 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
x.x.x Release notes (yyyy-MM-dd)
=============================================================
### Enhancements
* None.
* Creating an object for a class that has no subscriptions opened for it will throw an exception. ([realm/realm-core#5488](https://github.com/realm/realm-core/pull/5488))

### Fixed
* <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?)
* Add canonical schema type for returned schemas ([#4580](https://github.com/realm/realm-js/pull/4580))
* Fixed invalid type for schema properties([#4577](https://github.com/realm/realm-js/pull/4577)).
* Add canonical schema type for returned schemas. ([#4580](https://github.com/realm/realm-js/pull/4580))
* Fixed invalid type for schema properties. ([#4577](https://github.com/realm/realm-js/pull/4577))
* FLX sync subscription state changes will now correctly be reported after sync progress is reported. ([realm/realm-core#5553](https://github.com/realm/realm-core/pull/5553), since v10.18.0)

### Compatibility
* MongoDB Realm Cloud.
Expand All @@ -15,6 +15,8 @@ x.x.x Release notes (yyyy-MM-dd)
* File format: generates Realms with format v22 (reads and upgrades file format v5 or later for non-synced Realm, upgrades file format v10 or later for synced Realms).

### Internal
* Upgraded Realm Core from v12.0.0 to v12.1.0.
* Fix for updated FLX sync error message. ([#4611](https://github.com/realm/realm-js/pull/4611))
* Updated build script to use Xcode 13.1 to match latest Apple App Store compatibility. ([#4605](https://github.com/realm/realm-js/issues/4605))

10.18.0 Release notes (2022-5-29)
Expand Down
18 changes: 9 additions & 9 deletions integration-tests/tests/src/tests/sync/flexible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import Realm, { BSON, ClientResetMode, FlexibleSyncConfiguration, SessionStopPol

import { authenticateUserBefore, importAppBefore, openRealmBeforeEach } from "../../hooks";
import { DogSchema, IPerson, PersonSchema } from "../../schemas/person-and-dog-with-object-ids";
import { expectClientResetError } from "../../utils/expect-sync-error";
import { closeAndReopenRealm, closeRealm, closeThisRealm } from "../../utils/close-realm";
import { expectInvalidWriteSyncError } from "../../utils/expect-sync-error";
import { closeAndReopenRealm, closeRealm } from "../../utils/close-realm";

const FlexiblePersonSchema = { ...PersonSchema, properties: { ...PersonSchema.properties, nonQueryable: "string?" } };

Expand Down Expand Up @@ -1568,9 +1568,9 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () {

// TODO test more complex integration scenarios, e.g. links, embedded objects, collections, complex queries

describe("client reset scenarios", function () {
it("triggers a client reset if items are added without a subscription", async function (this: RealmContext) {
await expectClientResetError(this.config, this.user, (realm) => {
describe("error scenarios", function () {
it("triggers an error if items are added without a subscription", async function (this: RealmContext) {
await expectInvalidWriteSyncError(this.config, this.user, (realm) => {
realm.write(() => {
return realm.create<IPerson>(FlexiblePersonSchema.name, {
_id: new BSON.ObjectId(),
Expand All @@ -1581,10 +1581,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () {
});
});

it("triggers a client reset and deletes the item if an item not matching the filter is created", async function (this: RealmContext) {
it("triggers an error and deletes the item if an item not matching the filter is created", async function (this: RealmContext) {
await addSubscriptionAndSync(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age < 30"));

await expectClientResetError(
await expectInvalidWriteSyncError(
this.config,
this.user,
(realm) => {
Expand All @@ -1602,8 +1602,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () {
);
});

it("triggers a client reset if you remove a subscription without waiting for server acknowledgement, then modify objects that were only matched by the now removed subscription", async function (this: RealmContext) {
await expectClientResetError(this.config, this.user, async (realm) => {
it("triggers an error if you remove a subscription without waiting for server acknowledgement, then modify objects that were only matched by the now removed subscription", async function (this: RealmContext) {
await expectInvalidWriteSyncError(this.config, this.user, async (realm) => {
const { sub } = await addSubscriptionForPersonAndSync(this.realm);

this.realm.subscriptions.update((mutableSubs) => {
Expand Down
3 changes: 2 additions & 1 deletion integration-tests/tests/src/tests/sync/mixed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function describeRoundtrip({

async function setupTest(realm: Realm) {
if (flexibleSync) {
realm.subscriptions.update((mutableSubs) => {
await realm.subscriptions.update((mutableSubs) => {
mutableSubs.add(realm.objects("MixedClass"));
});
await realm.subscriptions.waitForSynchronization();
Expand All @@ -94,6 +94,7 @@ function describeRoundtrip({
});

it("writes", async function (this: RealmContext) {
this.timeout(6000);
await setupTest(this.realm);

this._id = new Realm.BSON.ObjectId();
Expand Down
70 changes: 51 additions & 19 deletions integration-tests/tests/src/utils/expect-sync-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import { expect } from "chai";
import { openRealm } from "./open-realm";

type Error = Realm.SyncError | (Realm.ClientResetError & { message: string });

/**
* Open a new Realm and perform an action, expecting a sync error to occur. Will
* never resolve and therefore timeout if a sync error does not occur.
Expand All @@ -34,28 +36,58 @@ export async function expectSyncError(
config: Realm.Configuration,
user: Realm.User,
action: (realm: Realm) => void,
expectation: (error: Realm.SyncError | Realm.ClientResetError) => void,
expectation: (error: Error) => void,
): Promise<void> {
let handleError: Realm.ErrorCallback | undefined;

const configWithErrorHandler = { ...config };
if (!configWithErrorHandler.sync) {
throw new Error("Expected a sync config");
}

configWithErrorHandler.sync.error = (session, error) => {
if (handleError) handleError(session, error);
};
return new Promise((resolve, reject) => {
if (!config.sync) {
throw new Error("Expected a sync config");
}

const { realm } = await openRealm(configWithErrorHandler, user);

return new Promise((resolve) => {
handleError = (session, error) => {
expectation(error);
resolve();
// Shallow copy the sync configuration to modifying the original
const modifiedConfig: Realm.Configuration = {
...config,
sync: {
...config.sync,
error(_, error: Error) {
try {
expectation(error);
resolve();
} catch (err) {
reject(err);
}
},
},
};

action(realm);
openRealm(modifiedConfig, user).then(({ realm }) => action(realm), reject);
});
}

/**
* Expect a sync error to occur with a message about an invalid write.
* Optionally specify more expectations about the sync error. Will
* never resolve and therefore timeout if a sync error does not occur.
*
* @param config The Realm config to use
* @param user The Realm user to use
* @param action Callback receiving a Realm instance and containing the
* action(s) to take which should trigger a client reset error
* @param extraExpectation Optional callback receiving the sync error, in order to make more
* assertions about it
* @returns Promise which resolves if the sync error occurs
*/
export async function expectInvalidWriteSyncError(
config: Realm.Configuration,
user: Realm.User,
action: (realm: Realm) => void,
extraExpectation?: (error: Error) => void,
): Promise<void> {
return expectSyncError(config, user, action, (error) => {
expect(error.name).to.equal("Error");
expect(error.message).to.match(
/Client attempted a write that is outside of permissions or query filters; it has been reverted.*/,
);
if (extraExpectation) extraExpectation(error);
});
}

Expand All @@ -76,7 +108,7 @@ export async function expectClientResetError(
config: Realm.Configuration,
user: Realm.User,
action: (realm: Realm) => void,
extraExpectation?: (error: Realm.SyncError | Realm.ClientResetError) => void,
extraExpectation?: (error: Error) => void,
): Promise<void> {
return expectSyncError(config, user, action, (error) => {
expect(error.name).to.equal("ClientReset");
Expand Down
2 changes: 1 addition & 1 deletion vendor/realm-core
Submodule realm-core updated 91 files
+27 −1 CHANGELOG.md
+3 −3 Jenkinsfile
+9 −343 Package.swift
+2 −2 dependencies.list
+7 −6 doc/changeset.md
+56 −6 evergreen/config.yml
+48 −15 evergreen/install_baas.sh
+3 −3 how-to-build.md
+28 −19 src/realm.h
+6 −1 src/realm/cluster.cpp
+16 −10 src/realm/db.cpp
+6 −9 src/realm/db.hpp
+10 −0 src/realm/exceptions.hpp
+5 −1 src/realm/exec/realm_trawler.cpp
+30 −7 src/realm/group.cpp
+34 −24 src/realm/group.hpp
+5 −10 src/realm/impl/copy_replication.cpp
+3 −3 src/realm/impl/copy_replication.hpp
+1 −0 src/realm/list.cpp
+1 −3 src/realm/mixed.hpp
+8 −0 src/realm/obj.cpp
+10 −11 src/realm/object-store/c_api/notifications.cpp
+6 −5 src/realm/object-store/c_api/sync.cpp
+16 −1 src/realm/object-store/c_api/types.hpp
+25 −0 src/realm/object-store/impl/realm_coordinator.cpp
+11 −1 src/realm/object-store/object_accessor.hpp
+41 −2 src/realm/object-store/object_schema.cpp
+6 −0 src/realm/object-store/object_schema.hpp
+23 −5 src/realm/object-store/object_store.cpp
+33 −27 src/realm/object-store/sync/sync_session.cpp
+1 −1 src/realm/object-store/sync/sync_session.hpp
+7 −1 src/realm/object-store/sync/sync_user.hpp
+1 −1 src/realm/parser/CMakeLists.txt
+7 −0 src/realm/query.cpp
+4 −2 src/realm/replication.cpp
+6 −6 src/realm/replication.hpp
+3 −1 src/realm/set.cpp
+8 −7 src/realm/sync/changeset.cpp
+17 −5 src/realm/sync/changeset_encoder.cpp
+135 −77 src/realm/sync/changeset_parser.cpp
+19 −10 src/realm/sync/changeset_parser.hpp
+7 −13 src/realm/sync/client.cpp
+2 −2 src/realm/sync/client_base.hpp
+5 −1 src/realm/sync/config.cpp
+6 −1 src/realm/sync/config.hpp
+14 −13 src/realm/sync/instruction_applier.cpp
+30 −21 src/realm/sync/instruction_replication.cpp
+14 −2 src/realm/sync/instruction_replication.hpp
+9 −7 src/realm/sync/instructions.hpp
+9 −0 src/realm/sync/noinst/client_history_impl.cpp
+30 −17 src/realm/sync/noinst/client_history_impl.hpp
+37 −19 src/realm/sync/noinst/client_impl_base.cpp
+6 −4 src/realm/sync/noinst/client_impl_base.hpp
+3 −2 src/realm/sync/noinst/client_reset.cpp
+39 −5 src/realm/sync/noinst/protocol_codec.hpp
+1 −1 src/realm/sync/noinst/sync_metadata_schema.cpp
+4 −0 src/realm/sync/protocol.cpp
+39 −4 src/realm/sync/protocol.hpp
+33 −12 src/realm/sync/subscriptions.cpp
+12 −2 src/realm/sync/subscriptions.hpp
+14 −8 src/realm/sync/transform.cpp
+72 −25 src/realm/table.cpp
+45 −9 src/realm/table.hpp
+2 −2 src/realm/util/compression.cpp
+ test/downgrade_asymmetric.realm
+6 −1 test/object-store/CMakeLists.txt
+6 −0 test/object-store/audit.cpp
+17 −12 test/object-store/c_api/c_api.cpp
+81 −0 test/object-store/object.cpp
+56 −2 test/object-store/schema.cpp
+399 −34 test/object-store/sync/flx_sync.cpp
+5 −0 test/object-store/sync/flx_sync_harness.hpp
+1 −1 test/object-store/sync/sync_test_utils.cpp
+61 −21 test/object-store/util/baas_admin_api.cpp
+10 −0 test/object-store/util/baas_admin_api.hpp
+18 −1 test/test_changeset_encoding.cpp
+13 −13 test/test_embedded_objects.cpp
+14 −14 test/test_group.cpp
+1 −1 test/test_instruction_replication.cpp
+2 −2 test/test_json.cpp
+2 −2 test/test_lang_bind_helper.cpp
+4 −2 test/test_links.cpp
+10 −0 test/test_query.cpp
+11 −11 test/test_shared.cpp
+1 −1 test/test_sync.cpp
+44 −0 test/test_sync_subscriptions.cpp
+36 −7 test/test_table.cpp
+4 −4 test/test_transform.cpp
+32 −0 test/test_typed_links.cpp
+1 −1 test/test_unresolved_links.cpp
+17 −0 test/test_upgrade_database.cpp

0 comments on commit 276c190

Please sign in to comment.