public async Task LoadAsync_Cancel_DomainClientCompletes()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);
            var city = new City()
            {
                Name = "NewCity", StateName = "NN", CountyName = "NewCounty"
            };

            // If cancellation results in request beeing cancelled the result should be cancelled
            var tcs = new TaskCompletionSource <QueryCompletedResult>();

            using var cts = new CancellationTokenSource();
            mockDomainClient.QueryCompletedResult = tcs.Task;
            var loadTask = ctx.LoadAsync(ctx.GetCitiesQuery(), cts.Token);

            cts.Cancel();
            tcs.SetResult(new QueryCompletedResult(new[] { city }, Array.Empty <Entity>(), -1, Array.Empty <ValidationResult>()));

            var result = await loadTask;

            Assert.AreEqual(1, result.Entities.Count);
            Assert.AreSame(city, result.Entities.First());
        }
        public void Invoke_ValidationErrors()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            ValidationResult[] validationErrors = new ValidationResult[] { new ValidationResult("Foo", new string[] { "Bar" }) };
            mockDomainClient.InvokeCompletedResult = Task.FromResult(new InvokeCompletedResult(null, validationErrors));
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);
            string myState = "Test User State";

            InvokeOperation invoke = ctx.Echo("TestInvoke", TestHelperMethods.DefaultOperationAction, myState);

            this.EnqueueCompletion(() => invoke);
            EnqueueCallback(delegate
            {
                Assert.IsNotNull(invoke.Error);
                Assert.AreSame(myState, invoke.UserState);

                CollectionAssert.AreEqual(validationErrors, (ICollection)invoke.ValidationErrors);

                // verify the exception properties
                var ex = (DomainOperationException)invoke.Error;
                Assert.AreEqual(OperationErrorStatus.ValidationFailed, ex.Status);
                CollectionAssert.AreEqual(validationErrors, (ICollection)ex.ValidationErrors);
                Assert.AreEqual(string.Format(Resource.DomainContext_InvokeOperationFailed_Validation, "Echo"), ex.Message);
            });

            EnqueueTestComplete();
        }
 public void TestInitialize()
 {
     this.Error = null;
     this.LoadOperation = null;
     this.SubmitOperation = null;
     this.CityDomainContext = new CityDomainContext(TestURIs.Cities);
 }
        public async Task SubmitAsync_Cancel_DomainClientCancel()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If cancellation results in request beeing cancelled the result should be cancelled
            var tcs = new TaskCompletionSource <SubmitCompletedResult>();

            using var cts = new CancellationTokenSource();
            mockDomainClient.SubmitCompletedResult = tcs.Task;

            ctx.Cities.Add(new City()
            {
                Name = "NewCity", StateName = "NN", CountyName = "NewCounty"
            });

            var submitTask = ctx.SubmitChangesAsync(cts.Token);

            cts.Cancel();
            Assert.IsTrue(ctx.IsSubmitting);
            Assert.IsTrue(ctx.Cities.First().IsSubmitting, "entity should be in submitting state");

            // Return cancellation from domain client
            tcs.TrySetCanceled(cts.Token);

            await ExceptionHelper.ExpectExceptionAsync <TaskCanceledException>(() => submitTask);

            Assert.IsTrue(submitTask.IsCanceled);
            Assert.IsFalse(ctx.IsSubmitting);
            Assert.IsFalse(ctx.Cities.First().IsSubmitting, "entity should not be in submitting state");
        }
        public void Submit()
        {
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(new CitiesMockDomainClient());
            string myState = "Test User State";

            Cities.Zip newZip = new Cities.Zip
            {
                Code      = 93551,
                FourDigit = 1234,
                CityName  = "Issaquah",
                StateName = "Issaquah"
            };
            ctx.Zips.Add(newZip);
            SubmitOperation so = ctx.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);

            this.EnqueueCompletion(() => so);
            EnqueueCallback(delegate
            {
                // verify that validation logic is run
                Assert.IsNotNull(so.Error);
                Assert.AreSame(newZip, so.EntitiesInError.Single());

                // fix by setting the Name
                newZip.StateName = "WA";
                so = ctx.SubmitChanges(null, myState);
            });
            this.EnqueueCompletion(() => so);
            EnqueueCallback(delegate
            {
                Assert.IsNull(so.Error);
                Assert.AreEqual(myState, so.UserState);
            });

            EnqueueTestComplete();
        }
        public async Task Submit_Cancel_DomainClientCancel()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If cancellation results in request beeing cancelled the result should be cancelled
            var tcs = new TaskCompletionSource <SubmitCompletedResult>();

            mockDomainClient.SubmitCompletedResult = tcs.Task;

            ctx.Cities.Add(new City()
            {
                Name = "NewCity", StateName = "NN", CountyName = "NewCounty"
            });

            var submitOp = ctx.SubmitChanges();

            submitOp.Cancel();
            Assert.IsTrue(submitOp.IsCancellationRequested);
            Assert.IsFalse(submitOp.IsCanceled);
            Assert.IsTrue(ctx.IsSubmitting);
            Assert.IsTrue(ctx.Cities.First().IsSubmitting, "entity should be in submitting state");

            tcs.TrySetCanceled(submitOp.CancellationToken);
            await submitOp;

            // Return cancellation from domain client
            Assert.IsTrue(submitOp.IsCanceled);
            Assert.IsFalse(ctx.IsSubmitting);
            Assert.IsFalse(ctx.Cities.First().IsSubmitting, "entity should not be in submitting state");
        }
        public void Load_ValidationErrors()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            ValidationResult[] validationErrors = new ValidationResult[] { new ValidationResult("Foo", new string[] { "Bar" }) };
            mockDomainClient.QueryCompletedResult = Task.FromResult(new QueryCompletedResult(Enumerable.Empty <Entity>(), Enumerable.Empty <Entity>(), 0, validationErrors));
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);
            string myState = "Test User State";

            LoadOperation <Cities.City> loadOperation = ctx.Load(ctx.GetCitiesQuery(), LoadBehavior.RefreshCurrent, l => l.MarkErrorAsHandled(), myState);;

            this.EnqueueCompletion(() => loadOperation);
            EnqueueCallback(delegate
            {
                Assert.AreSame(myState, loadOperation.UserState);

                CollectionAssert.AreEqual(validationErrors, (ICollection)loadOperation.ValidationErrors);

                // verify the exception properties
                var ex = loadOperation.Error as DomainOperationException;
                Assert.IsNotNull(ex, "expected exception of type DomainOperationException");
                Assert.AreEqual(OperationErrorStatus.ValidationFailed, ex.Status);
                Assert.AreEqual(string.Format(Resource.DomainContext_LoadOperationFailed_Validation, "GetCities"), ex.Message);
            });

            EnqueueTestComplete();
        }
        public void Paging()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._pagedCollectionView.PageSize = 10;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(10, this._view.Count, "this._ecv.Count should be 10 after the initial load");
                Assert.AreEqual(10, context.Cities.Count, "context.Cities.Count should be 10 after the initial load");

                this._view.MoveToNextPage();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(1, this._view.Count, "this._ecv.Count should be 1 after moving to the 2nd page");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after moving to the 2nd page");

                this._dds.PageSize = 0;
                Assert.AreEqual(0, this._dds.PageSize, "DDS PageSize should immediately reflect 0");
                Assert.AreEqual(0, this._view.PageSize, "this._ecv.PageSize should immediately reflect 0");
                Assert.AreEqual(-1, this._view.PageIndex, "this._ecv.PageIndex should immediately reflect -1");

                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after turning off paging and reloading");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after turning off paging and reloading");
                Assert.AreEqual(-1, this._view.PageIndex, "this._ecv.PageIndex should remain -1 after reloading");
            });

            EnqueueTestComplete();
        }
        public async Task Load_Cancel_DomainClientCancel()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If cancellation results in request beeing cancelled the result should be cancelled
            var tcs = new TaskCompletionSource <QueryCompletedResult>();

            mockDomainClient.QueryCompletedResult = tcs.Task;
            var loadOp = ctx.Load(ctx.GetCitiesQuery());

            loadOp.Cancel();

            Assert.IsTrue(loadOp.IsCancellationRequested);
            Assert.IsTrue(ctx.IsLoading);
            Assert.IsFalse(loadOp.IsCanceled);
            Assert.IsFalse(loadOp.IsComplete);

            tcs.TrySetCanceled(loadOp.CancellationToken);
            await loadOp;

            Assert.IsFalse(ctx.IsLoading);
            Assert.IsTrue(loadOp.IsCanceled);
            Assert.IsTrue(loadOp.IsComplete);
            Assert.IsFalse(loadOp.HasError, "Cancelled operation should not have any error");
        }
        public async Task SubmitAsync_Exceptions()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);
            DomainOperationException ex  = new DomainOperationException("Submit Failed!", OperationErrorStatus.ServerError, 42, "StackTrace");

            // If cancellation results in request beeing cancelled the result should be cancelled
            mockDomainClient.SubmitCompletedResult = Task.FromException <SubmitCompletedResult>(ex);

            ctx.Cities.Add(new City()
            {
                Name = "NewCity", StateName = "NN", CountyName = "NewCounty"
            });

            Assert.IsTrue(ctx.EntityContainer.HasChanges);
            var submitEx = await ExceptionHelper.ExpectExceptionAsync <SubmitOperationException>(() => ctx.SubmitChangesAsync());

            // verify the exception properties
            Assert.AreEqual(string.Format(Resource.DomainContext_SubmitOperationFailed, ex.Message), submitEx.Message);
            Assert.AreEqual(ex.StackTrace, submitEx.StackTrace);
            Assert.AreEqual(ex.Status, submitEx.Status);
            Assert.AreEqual(ex.ErrorCode, submitEx.ErrorCode);
            Assert.IsTrue(ctx.EntityContainer.HasChanges);

            // now test with validation exception
            var changeSet = ctx.EntityContainer.GetChanges();
            IEnumerable <ChangeSetEntry> entries = ChangeSetBuilder.Build(changeSet);
            ChangeSetEntry entry = entries.First();

            entry.ValidationErrors = new ValidationResultInfo[] { new ValidationResultInfo("Foo", new string[] { "Bar" }) };

            mockDomainClient.SubmitCompletedResult = Task.FromResult(new SubmitCompletedResult(changeSet, entries));
            submitEx = await ExceptionHelper.ExpectExceptionAsync <SubmitOperationException>(() => ctx.SubmitChangesAsync());

            // verify the exception properties
            Assert.AreEqual(Resource.DomainContext_SubmitOperationFailed_Validation, submitEx.Message);
            Assert.AreEqual(OperationErrorStatus.ValidationFailed, submitEx.Status);
            Assert.AreEqual(1, submitEx.EntitiesInError.Count);
            Assert.AreEqual(entry.ClientEntity, submitEx.EntitiesInError.First());

            // now test again with conflicts
            entries = ChangeSetBuilder.Build(changeSet);
            entry   = entries.First();
            entry.ConflictMembers = new string[] { nameof(City.CountyName) };
            entry.StoreEntity     = new City()
            {
                CountyName = "OtherCounty"
            };

            mockDomainClient.SubmitCompletedResult = Task.FromResult(new SubmitCompletedResult(changeSet, entries));
            submitEx = await ExceptionHelper.ExpectExceptionAsync <SubmitOperationException>(() => ctx.SubmitChangesAsync());

            // verify the exception properties
            Assert.AreEqual(Resource.DomainContext_SubmitOperationFailed_Conflicts, submitEx.Message);
            Assert.AreEqual(OperationErrorStatus.Conflicts, submitEx.Status);
            Assert.AreEqual(1, submitEx.EntitiesInError.Count);
            Assert.AreEqual(entry.ClientEntity, submitEx.EntitiesInError.First());
        }
        public void ExogenousDomainClient()
        {
            Cities.CityDomainContext ctxt1 = new CityDomainContext(TestURIs.Cities);
            Cities.CityDomainContext ctxt2 = new CityDomainContext(TestURIs.Cities);

            var q1 = ctxt1.GetCitiesInStateQuery("OH");

            ExceptionHelper.ExpectInvalidOperationException(delegate
            {
                ctxt2.Load(q1, false);
            }, string.Format(Resource.DomainContext_InvalidEntityQueryDomainClient, q1.QueryName));
        }
        public async Task Load()
        {
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(new CitiesMockDomainClient());
            string myState = "Test User State";

            var           query = ctx.GetCitiesQuery().Where(p => p.StateName == "WA").OrderBy(p => p.CountyName).Take(4);
            LoadOperation lo    = ctx.Load(query, TestHelperMethods.DefaultOperationAction, myState);

            await lo;

            Assert.IsNull(lo.Error);
            Assert.AreEqual(4, ctx.Cities.Count);
            Assert.IsTrue(ctx.Cities.All(p => p.StateName == "WA"));
            Assert.AreEqual(myState, lo.UserState);
        }
        public async Task LoadAsync_ValidationErrors()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            ValidationResult[] validationErrors = new ValidationResult[] { new ValidationResult("Foo", new string[] { "Bar" }) };
            mockDomainClient.QueryCompletedResult = Task.FromResult(new QueryCompletedResult(Enumerable.Empty <Entity>(), Enumerable.Empty <Entity>(), 0, validationErrors));
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            var ex = await ExceptionHelper.ExpectExceptionAsync <DomainOperationException>(
                () => ctx.LoadAsync(ctx.GetCitiesQuery()),
                string.Format(Resource.DomainContext_LoadOperationFailed_Validation, "GetCities"));

            // verify the exception properties
            Assert.AreEqual(OperationErrorStatus.ValidationFailed, ex.Status);
            CollectionAssert.AreEqual(validationErrors, (ICollection)ex.ValidationErrors);
        }
        public async Task InvokeAsync_ValidationErrors()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            ValidationResult[] validationErrors = new ValidationResult[] { new ValidationResult("Foo", new string[] { "Bar" }) };
            mockDomainClient.InvokeCompletedResult = Task.FromResult(new InvokeCompletedResult(null, validationErrors));
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            var ex = await ExceptionHelper.ExpectExceptionAsync <DomainOperationException>(
                () => ctx.EchoAsync("TestInvoke"),
                string.Format(Resource.DomainContext_InvokeOperationFailed_Validation, "Echo"));

            // verify the exception properties
            Assert.AreEqual(OperationErrorStatus.ValidationFailed, ex.Status);
            CollectionAssert.AreEqual(validationErrors, (ICollection)ex.ValidationErrors);
        }
        public void Invoke()
        {
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(new CitiesMockDomainClient());
            string myState = "Test User State";

            InvokeOperation invoke = ctx.Echo("TestInvoke", TestHelperMethods.DefaultOperationAction, myState);

            this.EnqueueCompletion(() => invoke);
            EnqueueCallback(delegate
            {
                Assert.IsNull(invoke.Error);
                Assert.AreSame(myState, invoke.UserState);
                Assert.AreEqual("Echo: TestInvoke", invoke.Value);
            });

            EnqueueTestComplete();
        }
        public void Cities_VerifyCustomHost()
        {
            CityDomainContext dp = new CityDomainContext(TestURIs.Cities);    // Abs URI so runs on desktop too

            InvokeOperation<bool> invokeOp = dp.UsesCustomHost(TestHelperMethods.DefaultOperationAction, null);

            EnqueueConditional(() => invokeOp.IsComplete);

            EnqueueCallback(() =>
            {
                if (invokeOp.Error != null)
                    Assert.Fail("InvokeOperation.Error: " + invokeOp.Error.Message);
                Assert.IsTrue(invokeOp.Value, "CityDomainService isn't using a custom host.");
            });

            EnqueueTestComplete();
        }
        public void CancellationSupport()
        {
            var domainClient = new CitiesMockDomainClient();

            domainClient.SetSupportsCancellation(false);
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(domainClient);

            var           query = ctx.GetCitiesQuery();
            LoadOperation lo    = ctx.Load(query, false);

            Assert.IsFalse(lo.CanCancel, "Cancellation should not be supported.");
            Assert.IsFalse(ctx.DomainClient.SupportsCancellation, "Cancellation should not be supported.");

            ExceptionHelper.ExpectException <NotSupportedException>(delegate
            {
                lo.Cancel();
            }, string.Format(CultureInfo.CurrentCulture, Resources.AsyncOperation_CancelNotSupported));
        }
        public async Task InvokeAsync_DomainOperationException()
        {
            var mockDomainClient = new CitiesMockDomainClient();
            DomainOperationException exception = new DomainOperationException("Operation Failed!", OperationErrorStatus.ServerError, 42, "StackTrace");

            mockDomainClient.InvokeCompletedResult = Task.FromException <InvokeCompletedResult>(exception);
            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            var ex = await ExceptionHelper.ExpectExceptionAsync <DomainOperationException>(
                () => ctx.EchoAsync("TestInvoke"),
                string.Format(Resource.DomainContext_InvokeOperationFailed, "Echo", exception.Message));

            // verify the exception properties
            Assert.AreEqual(null, ex.InnerException);
            Assert.AreEqual(ex.StackTrace, exception.StackTrace);
            Assert.AreEqual(ex.Status, exception.Status);
            Assert.AreEqual(ex.ErrorCode, exception.ErrorCode);
        }
        public async Task InvokeAsync_Cancel_DomainClientCancel()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If cancellation results in request beeing cancelled the result should be cancelled
            var tcs = new TaskCompletionSource <InvokeCompletedResult>();

            using var cts = new CancellationTokenSource();
            mockDomainClient.InvokeCompletedResult = tcs.Task;
            var invokeTask = ctx.EchoAsync("TestInvoke", cts.Token);

            cts.Cancel();
            tcs.TrySetCanceled(cts.Token);

            await ExceptionHelper.ExpectExceptionAsync <TaskCanceledException>(() => invokeTask);

            Assert.IsTrue(invokeTask.IsCanceled);
        }
        public async Task InvokeAsync_Cancel_DomainClientCompletes()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If the web requires returns a value even if cancelled
            // It should still return a result
            var tcs = new TaskCompletionSource <InvokeCompletedResult>();

            using var cts = new CancellationTokenSource();
            mockDomainClient.InvokeCompletedResult = tcs.Task;
            var invokeTask = ctx.EchoAsync("TestInvoke", cts.Token);

            cts.Cancel();
            tcs.SetResult(new InvokeCompletedResult("Res"));

            var res = await invokeTask;

            Assert.AreEqual("Res", res.Value);
        }
        public async Task SubmitAsync_Cancel_DomainClientCompletes()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If cancellation results in request beeing cancelled the result should be cancelled
            using var cts = new CancellationTokenSource();
            mockDomainClient.SubmitCompletedCallback = async(changeSet, submitOperations) =>
            {
                // Wait for cancellation, and then return successfully without cancellation
                try
                {
                    await Task.Delay(-1, cts.Token);
                }
                catch (OperationCanceledException)
                {
                    // Do nothing this is the expected outcome
                }
                // perform mock submit operations
                SubmitCompletedResult submitResults = new SubmitCompletedResult(changeSet, submitOperations);
                return(submitResults);
            };

            ctx.Cities.Add(new City()
            {
                Name = "NewCity", StateName = "NN", CountyName = "NewCounty"
            });

            var submitTask = ctx.SubmitChangesAsync(cts.Token);

            Assert.IsTrue(ctx.IsSubmitting);
            Assert.IsTrue(ctx.Cities.First().IsSubmitting, "entity should be in submitting state");
            cts.Cancel();

            var result = await submitTask;

            Assert.IsFalse(ctx.IsSubmitting);
            Assert.IsFalse(ctx.Cities.First().IsSubmitting, "entity should not be in submitting state");
        }
        public async Task LoadAsync_Cancel_DomainClientCancel()
        {
            var mockDomainClient = new CitiesMockDomainClient();

            Cities.CityDomainContext ctx = new Cities.CityDomainContext(mockDomainClient);

            // If cancellation results in request beeing cancelled the result should be cancelled
            var tcs = new TaskCompletionSource <QueryCompletedResult>();

            using var cts = new CancellationTokenSource();
            mockDomainClient.QueryCompletedResult = tcs.Task;
            var loadTask = ctx.LoadAsync(ctx.GetCitiesQuery(), cts.Token);

            Assert.IsTrue(ctx.IsLoading);
            cts.Cancel();
            tcs.TrySetCanceled(cts.Token);

            await ExceptionHelper.ExpectExceptionAsync <OperationCanceledException>(() => loadTask, allowDerivedExceptions : true);

            Assert.IsTrue(loadTask.IsCanceled);
            Assert.IsFalse(ctx.IsLoading);
        }
        public void Cities_LoadStates_TestEnums()
        {
            CityDomainContext dp = new CityDomainContext(TestURIs.Cities);

            SubmitOperation so = null;
            LoadOperation lo = dp.Load(dp.GetStatesQuery().Where(s => s.TimeZone == Cities.TimeZone.Pacific), false);

            EnqueueConditional(() => lo.IsComplete);

            EnqueueCallback(() =>
            {
                if (lo.Error != null)
                    Assert.Fail("LoadOperation.Error: " + lo.Error.Message);

                // verify the TimeZones were serialized to the client properly
                State state = dp.States.Single(p => p.Name == "WA");
                Assert.AreEqual(Cities.TimeZone.Pacific, state.TimeZone);

                Assert.IsFalse(dp.States.Any(p => p.Name == "OH"));

                // Now test update
                state.TimeZone = state.TimeZone = Cities.TimeZone.Central;
                Assert.AreEqual(EntityState.Modified, state.EntityState);

                EntityChangeSet cs = dp.EntityContainer.GetChanges();
                Assert.IsTrue(cs.ModifiedEntities.Contains(state));

                so = dp.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);
            });
            EnqueueConditional(() => so.IsComplete);
            EnqueueCallback(() =>
            {
                TestHelperMethods.AssertOperationSuccess(so);
            });

            EnqueueTestComplete();
        }
        public void RemovingAndAddingFromSharedDomainContext()
        {
            DomainDataSourceView data1 = null;
            DomainDataSourceView data2 = null;

            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 2;
                this._dds.Load();
            });

            this.AssertLoadingData();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();

                // Grab a hold of the loaded data and create a new one
                data1 = this._view;
                Assert.AreEqual(2, context.Cities.Count, "context.Cities.Count should be 2 after loading the 1st dds");

                this.Initialize();

                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadingData();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();

                data2 = this._view;

                Assert.AreEqual(2, data1.Count, "data1.Count should be 2 after loading the 2nd DDS");
                Assert.AreEqual(11, data2.Count, "data2.Count should be 11 after loading the 2nd DDS");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after loading the 2nd DDS");

                City city = data1[0] as City;
                data1.Remove(city);
                Assert.AreEqual(1, data1.Count, "data1.Count should be 1 after removing an item");
                Assert.AreEqual(10, data2.Count, "data2.Count should be 10 after removing an item from the data1");
                Assert.AreEqual(10, context.Cities.Count, "context.Cities.Count should be 10 after removing an item from data1");

                context.Cities.Add(city);
                Assert.AreEqual(2, data1.Count, "data1.Count should be 2 after adding the item back to the context");
                Assert.AreEqual(11, data2.Count, "data2.Count should be 11 after adding the item back to the context");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after adding the item back to the context");

                city = data2[8] as City;
                data2.Remove(city);
                Assert.AreEqual(2, data1.Count, "data1.Count should be 2 after removing an item from data2 that doesn't exist in data1");
                Assert.AreEqual(10, data2.Count, "data2.Count should be 10 after removing an item1");
                Assert.AreEqual(10, context.Cities.Count, "context.Cities.Count should be 10 after removing an item from data2");

                context.Cities.Add(city);
                Assert.AreEqual(2, data1.Count, "data1.Count should be 2 after adding the item back to the context");
                Assert.AreEqual(11, data2.Count, "data2.Count should be 11 after adding the item back to the context");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after adding the item back to the context");
            });

            EnqueueTestComplete();
        }
        public void RemovingFromDataView()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                Assert.IsFalse(this._dds.HasChanges, "this._dds.HasChanges should be false after the initial load");
                Assert.IsFalse(context.HasChanges, "context.HasChanges should be false after the initial load");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after the initial load");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after the initial load");

                City city = this._view[0] as City;

                this._view.Remove(city);
                Assert.AreEqual(10, context.Cities.Count, "context.Cities.Count should be 10 after removing a city");
                Assert.AreEqual(10, this._view.Count, "this._ecv.Count should be 10 after removing a city");
                Assert.IsTrue(context.HasChanges, "context.HasChanges should be true after Remove");
                Assert.IsTrue(this._dds.HasChanges, "this._dds.HasChanges should be true after Remove");

                context.Cities.Add(city);
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after adding the city back");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after adding the city back");
                Assert.IsFalse(context.HasChanges, "context.HasChanges should be false after adding the city back");
                Assert.IsFalse(this._dds.HasChanges, "this._dds.HasChanges should be false after adding the city back");
            });

            EnqueueTestComplete();
        }
        public void AddingToDataView()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.AutoLoad = false;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.SortDescriptors.Add(new SortDescriptor("Name", ListSortDirection.Ascending));
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                Assert.IsFalse(this._dds.HasChanges, "this._dds.HasChanges should be false after the initial load");
                Assert.IsFalse(context.HasChanges, "context.HasChanges should be false after the initial load");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after the initial load");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after the initial load");

                City city = this._editableCollectionView.AddNew() as City;
                Assert.AreEqual(12, context.Cities.Count, "There should be 12 items in context after adding a new city");
                Assert.AreEqual(12, this._view.Count, "this._ecv.Count should be 12 after adding a new city");
                Assert.IsTrue(context.HasChanges, "context.HasChanges should be true after the AddNew");
                Assert.IsTrue(this._dds.HasChanges, "this._dds.HasChanges should be true after the AddNew");
                AssertHelper.AssertSequenceSorting(this._view.Cast<City>().Select(c => c.Name), ListSortDirection.Ascending, "The cities should be sorted by name after adding the city");
                city.Name = "Added City";
                city.StateName = "ST";

                this._editableCollectionView.CommitNew();
                Assert.AreEqual(12, context.Cities.Count, "There should be 12 items in context after the CommitNew");
                Assert.AreEqual(12, this._view.Count, "this._ecv.Count should be 12 after the CommitNew");
                Assert.IsTrue(context.HasChanges, "context.HasChanges should be true after the CommitNew");
                Assert.IsTrue(this._dds.HasChanges, "this._dds.HasChanges should be true after the CommitNew");
                AssertHelper.AssertSequenceSorting(this._view.Cast<City>().Select(c => c.Name), ListSortDirection.Ascending, "The cities should be sorted by name after committing the city");

                this._view.Remove(city);
                Assert.IsFalse(this._dds.HasChanges, "this._dds.HasChanges should be false after removing the new item");
                Assert.IsFalse(context.HasChanges, "context.HasChanges should be false after removing the new item");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after removing the new item");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after removing the new item");
            });

            EnqueueTestComplete();
        }
        public void SubmitChanges_ValidatesEntities()
        {
            CityDomainContext domainContext = new CityDomainContext();
            City newCity = new City();
            domainContext.Cities.Add(newCity);

            System.ComponentModel.INotifyDataErrorInfo notifier = (System.ComponentModel.INotifyDataErrorInfo)newCity;
            List<string> actualErrors = new List<string>();
            notifier.ErrorsChanged += (s, e) => actualErrors.Add(e.PropertyName);

            this.EnqueueCallback(() =>
            {
                // Required fields will be reported as in error
                this.SubmitOperation = domainContext.SubmitChanges();

                // The submission will fail because of the validation error.  Mark it as handled.
                this.SubmitOperation.Completed += (s, e) => this.SubmitOperation.MarkErrorAsHandled();

                Assert.IsTrue(newCity.ValidationErrors.Any(r => r.MemberNames.Contains("Name")), "Name is required");
                Assert.IsTrue(actualErrors.OrderBy(s => s).SequenceEqual(new string[] { "Name" }), "We should have received errors for Name");
                actualErrors.Clear();
            });

            this.EnqueueConditional(() => SubmitOperation.IsComplete);

            this.EnqueueCallback(() =>
            {
                newCity.Name = "West Chester";
                newCity.StateName = "OH";
                newCity.CountyName = "Butler"; // No validation - but needed for a complete key

                Assert.IsTrue(actualErrors.OrderBy(s => s).SequenceEqual(new string[] { "Name" }), "We should have received a notification for Name when setting it to a valid value");
                actualErrors.Clear();

                newCity.ZoneID = -50; // Invalid
                Assert.IsTrue(actualErrors.SequenceEqual(new string[] { "ZoneID" }), "We should have received an error for ZoneID when setting it to an invalid value");
                actualErrors.Clear();

                // Property errors will be reported
                this.SubmitOperation = domainContext.SubmitChanges();

                // The submission will fail because of the validation error.  Mark it as handled.
                this.SubmitOperation.Completed += (s, e) => this.SubmitOperation.MarkErrorAsHandled();

                Assert.IsTrue(newCity.ValidationErrors.Any(r => r.MemberNames.Contains("ZoneID")), "ZoneID is out of range");
                Assert.IsTrue(actualErrors.SequenceEqual(new string[] { "ZoneID" }), "We should have received an error for ZoneID only - errors were cleared and replaced");
                actualErrors.Clear();
            });

            this.EnqueueConditional(() => SubmitOperation.IsComplete);

            this.EnqueueCallback(() =>
            {
                newCity.StateName = "ASDF"; // Too long
                Assert.IsTrue(actualErrors.SequenceEqual(new string[] { "StateName" }), "We should have received an error for StateName when setting it to an invalid value");
                actualErrors.Clear();

                // Property errors will be reported
                this.SubmitOperation = domainContext.SubmitChanges();

                // The submission will fail because of the validation error.  Mark it as handled.
                this.SubmitOperation.Completed += (s, e) => this.SubmitOperation.MarkErrorAsHandled();

                Assert.IsTrue(newCity.ValidationErrors.Any(r => r.MemberNames.Contains("ZoneID")), "ZoneID is invalid");
                Assert.IsTrue(newCity.ValidationErrors.Any(r => r.MemberNames.Contains("StateName")), "StateName is too long");
                Assert.IsTrue(actualErrors.OrderBy(s => s).SequenceEqual(new string[] { "StateName", "ZoneID" }), "We should have received errors for StateName and ZoneID");
                actualErrors.Clear();
            });

            this.EnqueueConditional(() => SubmitOperation.IsComplete);

            this.EnqueueCallback(() =>
            {
                newCity.ZoneID = 0;
                newCity.StateName = "OH";
                Assert.IsTrue(actualErrors.OrderBy(s => s).SequenceEqual(new string[] { "StateName", "ZoneID" }), "We should have received notifications for StateName and ZoneID when setting them to valid values");
                actualErrors.Clear();

                // Force entity-level validation failure
                newCity.MakeEntityValidationFail = true;

                // The entity-level error will be reported
                this.SubmitOperation = domainContext.SubmitChanges();

                // The submission will fail because of the validation error.  Mark it as handled.
                this.SubmitOperation.Completed += (s, e) => this.SubmitOperation.MarkErrorAsHandled();

                Assert.IsTrue(newCity.ValidationErrors.Any(r => r.MemberNames == null || !r.MemberNames.Any(m => !string.IsNullOrEmpty(m))), "We should only have entity-level errors (no members or null or empty members only)");
                Assert.IsTrue(actualErrors.SequenceEqual(new string[] { null }), "We should have received an error for the entity-level error");
                actualErrors.Clear();
            });

            this.EnqueueConditional(() => SubmitOperation.IsComplete);

            this.EnqueueCallback(() =>
            {
                // Allow all validation to pass
                newCity.MakeEntityValidationFail = false;

                // The submission will succeed - there are no further validation errors.
                // But this will still result in notifications because the validation errors are cleared
                // To help verify this, we will add a validation result to the collection to ensure it's cleared
                newCity.ValidationErrors.Add(new ValidationResult("Added Error", new string[] { "MakeBelieveProperty" }));
                actualErrors.Clear();

                this.SubmitOperation = domainContext.SubmitChanges();

                Assert.IsTrue(!newCity.ValidationErrors.Any(), "There should not be any errors after valid submission");
                Assert.IsTrue(actualErrors.OrderBy(s => s).SequenceEqual(new string[] { null, "MakeBelieveProperty" }.OrderBy(s => s)), "We should have received notifications that the entity-level and property-level erros were cleared");
            });

            this.EnqueueConditional(() => SubmitOperation.IsComplete);

            this.EnqueueTestComplete();
        }
        public void PagingCollectionEventsWithServerPaging()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 3;

                this.TrackCollectionChanged();
                this._dds.Load();
            });

            this.AssertLoadingData();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(0, this._view.PageIndex, "PageIndex should be 0 after initial load");
                // TODO: Change from 2 Reset events to 1 when bug 709185 is fixed and our workaround can be removed
                this.AssertCollectionChanged(0, 0, 2, "Initial load");

                this._view.MoveToNextPage();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(1, this._view.PageIndex, "PageIndex should be 1 on the 2nd page");
                // TODO: Change from 2 Reset events to 1 when bug 709185 is fixed and our workaround can be removed
                this.AssertCollectionChanged(0, 0, 2, "Move to 2nd page");
            });

            EnqueueTestComplete();
        }
        public void AddingToCurrentPageIncreasesCount()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.AutoLoad = false;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 3;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            // Our submissions won't succeed with this domain context
            this._dds.SubmittedChanges += (s, e) =>
            {
                if (e.HasError)
                {
                    e.MarkErrorAsHandled();
                }
            };

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(3, this._view.Count, "3 items should have been loaded onto the page");
                Assert.AreEqual(3, context.Cities.Count, "context.Cities.Count should be 3 after the initial load");

                City newCity = this._editableCollectionView.AddNew() as City;
                newCity.Name = "West Chester";
                newCity.StateName = "OH";
                this._editableCollectionView.CommitNew();

                Assert.AreEqual(4, this._view.Count, "this._ecv.Count should be 4 after adding the new item");
                Assert.AreEqual(4, context.Cities.Count, "context.Cities.Count should be 4 after adding the new item");

                this._dds.SubmitChanges();
            });

            this.AssertSubmittingChanges();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();
                this.ResetSubmitState();

                this._dds.Load();
            });

            this.AssertLoadingData();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();
                this.ResetSubmitState();

                Assert.AreEqual(3, this._view.Count, "this._ecv.Count should return to 3 after submitting");
                Assert.AreEqual(4, context.Cities.Count, "context.Cities.Count should remain 4 after submitting");
            });

            EnqueueTestComplete();
        }
        public void EnumeratorReadyAfterInitialSinglePageLoad()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 5;

                this.TrackCollectionChanged();
                this._dds.Load();

                bool isInitialLoad = true;

                this._collectionView.CollectionChanged += (s, e) =>
                {
                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset && !isInitialLoad)
                    {
                        Assert.AreEqual(5, this._view.Count, "this._ecv.Count should be 5 when the Reset event occurs");
                    }

                    isInitialLoad = false;
                };
            });

            this.AssertLoadingData();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                int count = 0;
                City[] cities = context.Cities.ToArray();
                foreach (Entity entity in this._view)
                {
                    Assert.AreSame(cities[count++], entity, "Entity mismatch at index " + (count - 1).ToString());
                }

                Assert.AreEqual(5, count, "The enumerator should have had 5 items in it");
            });

            EnqueueTestComplete();
        }
        public void CustomMethod_ValidationExceptionRecovery()
        {
            bool completed = false;
            Zip zip = null;
            SubmitOperation submitOp = null;
            LoadOperation<Zip> loadOp = null;
            EventHandler completedDelegate = (sender, args) => completed = true;
            
            CityDomainContext context = new CityDomainContext(TestURIs.Cities);
            loadOp = context.Load(context.GetZipsQuery(), false);
            loadOp.Completed += completedDelegate;

            this.EnqueueConditional(() => completed);
            this.EnqueueCallback(() =>
            {
                Assert.IsFalse(loadOp.HasError, "Failed to load Zips");

                // Grab a Zip and invoke a custom operation that will throw a ValidationException.
                zip = context.Zips.First();
                zip.ThrowException(typeof(ValidationException).Name);

                // Submit
                completed = false;
                submitOp = context.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);
                submitOp.Completed += completedDelegate;

                // Verify entity state
                Assert.IsTrue(zip.IsReadOnly, "Expected Zip to be in a read-only state.");
                Assert.IsTrue(zip.IsSubmitting, "Expected Zip to be in a submitting state.");
                Assert.AreEqual(1, zip.EntityActions.Count(), "Expected Zip EntityActions property to contain a single invocation");
            });
            this.EnqueueConditional(() => completed);
            this.EnqueueCallback(() =>
            {
                // Verify results
                Assert.IsTrue(submitOp.HasError, "Expected errors.");
                Assert.AreEqual(1, submitOp.EntitiesInError.Count(), "Expected 1 Zip entity in error.");
                Assert.AreEqual(submitOp.EntitiesInError.Single(), zip, "Expected 1 Zip entity in error.");
                Assert.AreEqual(1, zip.ValidationErrors.Count, "Expected 1 validation error on Zip entity.");

                // Verify entity state
                Assert.IsFalse(zip.IsReadOnly, "Zip should not be in a read-only state.");
                Assert.IsFalse(zip.IsSubmitting, "Zip should not be in a submitting state.");
                Assert.AreEqual(1, zip.EntityActions.Count(), "Expected Zip EntityActions property to contain a single invocation");

                // Explicitly set a property
                zip.StateName += "x";
            });
            this.EnqueueTestComplete();
        }
        public void PagingPastEndSkippingLastPageUnknownTotalItemCount()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.PageSize = 6;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            Action<string> verifyFirstPageLoaded = (string message) =>
            {
                Assert.AreEqual(6, this._view.Count, message);
                Assert.AreEqual(0, this._view.PageIndex, message);
                Assert.AreEqual("Redmond", (this._view[0] as City).Name, message);
                Assert.AreEqual("Bellevue", (this._view[1] as City).Name, message);
                Assert.AreEqual("Duvall", (this._view[2] as City).Name, message);
                Assert.AreEqual("Carnation", (this._view[3] as City).Name, message);
                Assert.AreEqual("Everett", (this._view[4] as City).Name, message);
                Assert.AreEqual("Tacoma", (this._view[5] as City).Name, message);
            };

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                verifyFirstPageLoaded("First load");

                this._view.MoveToPage(5);
            });

            // Attempt to load the non-existent page, then load the first page
            this.AssertLoadingData(2);
            this.AssertNoPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                verifyFirstPageLoaded("After paging past the end");
            });

            EnqueueTestComplete();
        }
        public void LoadThreePagesAtOnce()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                // Paging and loading pattern: {(2,2,2), (2,2,1)}
                this._dds.LoadSize = 6;
                this._dds.PageSize = 2;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after the initial load");
                Assert.AreEqual(6, this._pagedCollectionView.ItemCount, "this._ecv.ItemCount should be 6 after the initial load");
                Assert.AreEqual(6, context.Cities.Count, "context.Cities.Count should be 6 after the initial load");

                this._ddsLoadingDataExpected = 0;
                this._view.MoveToNextPage();
            });

            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 2nd page");
                Assert.AreEqual(6, this._pagedCollectionView.ItemCount, "this._ecv.ItemCount should be 6 after moving to the 2nd page");
                Assert.AreEqual(6, context.Cities.Count, "context.Cities.Count should still be 6 after moving to the 2nd page");

                this._view.MoveToNextPage();
            });

            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 3rd page");
                Assert.AreEqual(6, this._pagedCollectionView.ItemCount, "this._ecv.ItemCount should be 6 after moving to the 3rd page");
                Assert.AreEqual(6, context.Cities.Count, "context.Cities.Count should be 6 after moving to the 3rd page");

                this._view.MoveToNextPage();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 4th page");
                Assert.AreEqual(11, this._pagedCollectionView.ItemCount, "this._ecv.ItemCount should be 11 after moving to the 4th page");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after moving to the 4th page");
            });

            EnqueueTestComplete();
        }
        public void LinqQueryWhenLoadingData()
        {
            EnqueueCallback(() =>
            {
                CityDomainContext context = new CityDomainContext();
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.LoadingData += (object sender, OpenRiaServices.Controls.LoadingDataEventArgs e) => e.Query = context.GetCitiesQuery().Where(c => c.StateName == "WA");
                this._dds.Load();
            });

            this.AssertLoadingData();

            EnqueueCallback(() =>
            {
                Assert.AreEqual(6, this._view.Count);
            });

            EnqueueTestComplete();
        }
        public void ClearThroughEntitySet()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 5;
                this._dds.Load();
            });

            this.AssertLoadingData();

            City loadedCity = null;

            EnqueueCallback(() =>
            {
                this.ResetLoadState();

                Assert.AreEqual<int>(this._dds.PageSize, this._view.Count, "this._view.Count after the load");
                Assert.AreEqual<int>(this._dds.PageSize, context.Cities.Count, "context.Cities.Count after the load");

                // Grab reference to a city that was loaded.  We'll use it later to ensure page tracking is kept intact.
                loadedCity = (City)this._view[0];

                context.Cities.Clear();
                Assert.AreEqual<int>(0, this._view.Count, "this._view.Count after Clear()");
                Assert.AreEqual<int>(0, context.Cities.Count, "context.Cities.Count after Clear()");

                // Add the loaded city back into the domain context, ensuring that page tracking adds it back to the view
                context.Cities.Add(loadedCity);
                Assert.AreEqual<int>(1, this._view.Count, "this._view.Count after adding the loaded city back to the context");
                Assert.IsTrue(this._view.Contains(loadedCity), "The view should contain the loaded city");
            });

            EnqueueTestComplete();
        }
        public void HasChangesAfterAddingItemToContext()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                Assert.IsFalse(this._dds.HasChanges, "DDS should not have changes before anything is edited");
                Assert.AreEqual(11, this._view.Count, "There should have been 11 items initially loaded");

                City city = new City { Name = "City Name", StateName = "ST" };
                context.Cities.Add(city);
                Assert.IsTrue(this._dds.HasChanges, "DDS should have changes after adding an item with AddNew");
            });

            EnqueueTestComplete();
        }
        public void RemovingAndRestoringItemFromAnotherPage()
        {
            CityDomainContext context = new CityDomainContext();
            City city = null;

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 5;
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                city = this._view[0] as City;

                this._view.MoveToNextPage();
            });

            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(5, this._view.Count, "this._ecv.Count should be 5 after loading the 2nd page");
                Assert.AreEqual(10, context.Cities.Count, "context.Cities.Count should be 10 after loading the 2nd page");

                context.Cities.Remove(city);
                Assert.AreEqual(5, this._view.Count, "this._ecv.Count should be 5 after removing the city, since it belongs to another page");
                Assert.AreEqual(9, context.Cities.Count, "context.Cities.Count should be 9 after removing the city");

                context.Cities.Add(city);
                Assert.AreEqual(5, this._view.Count, "this._ecv.Count should be 5 after restoring the removed city");
                Assert.AreEqual(10, context.Cities.Count, "context.Cities.Count should be 10 after restoring the removed city");

            });

            EnqueueTestComplete();
        }
        public void HasChangesAfterRemovingItemFromContext()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                Assert.IsFalse(this._dds.HasChanges, "DDS should not have changes before anything is edited");
                Assert.AreEqual(11, this._view.Count, "There should have been 11 items initially loaded");

                City city = context.Cities.First();
                context.Cities.Remove(city);
                Assert.IsTrue(this._dds.HasChanges, "DDS should have changes after removing an item from context");
            });

            EnqueueTestComplete();
        }
        public void CurrencySetAfterLocalPaging()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.PageSize = 3;
                this._dds.LoadSize = 11;

                this._asyncEventFailureMessage = "Initial Load";
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreSame(context.Cities.First(), this._view.CurrentItem, "CurrentItem should match the context.Cities[0] after the initial load");
                Assert.AreEqual(0, this._view.CurrentPosition, "CurrentPosition should be 0 after the initial load");
                this._ddsLoadedDataExpected = 0;

                this._asyncEventFailureMessage = "MoveToNextPage()";
                this._view.MoveToNextPage();
            });

            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                City[] cities = context.Cities.ToArray();
                Assert.AreSame(cities[3], this._view.CurrentItem, "CurrentItem should match the context.Cities[3] after MoveToNextPage()");
                Assert.AreEqual(0, this._view.CurrentPosition, "CurrentPosition should be 0 after MoveToNextPage()");
            });

            EnqueueTestComplete();
        }
        public void DataInSyncWithContextAfterRemoveFromContext()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                Assert.AreEqual(11, this._view.Count, "There should have been 11 items initially loaded");

                context.Cities.Remove(context.Cities.First());
                Assert.AreEqual(10, this._view.Count, "There should only be 10 items in Data after the remove");
                Assert.AreEqual(10, context.Cities.Count, "There should only be 10 items in context.Cities after the remove");

                foreach (City city in this._view)
                {
                    Assert.IsTrue(context.Cities.Contains(city), "Context should have all cities from this._ecv.  Missing City: " + city.Name + ", " + city.StateName);
                }
            });

            EnqueueTestComplete();
        }
        public void CustomMethodFlag_ChangeNotifications()
        {
            List<string> propChanged = new List<string>();
            CityDomainContext ctxt = new CityDomainContext(TestURIs.Cities);
            City city = null;

            LoadOperation lo = ctxt.Load(ctxt.GetCitiesQuery(), false);
            SubmitOperation so = null;

            EnqueueConditional(() => lo.IsComplete);
            EnqueueCallback(delegate
            {
                city = ctxt.Cities.First();

                city.PropertyChanged += (s, e) =>
                {
                    propChanged.Add(e.PropertyName);
                };

                Assert.IsTrue(city.CanAssignCityZone);
                Assert.IsFalse(city.IsAssignCityZoneInvoked);

                city.AssignCityZone("Twilight");

                Assert.IsFalse(city.CanAssignCityZone);
                Assert.IsTrue(city.IsAssignCityZoneInvoked);

                Assert.IsTrue(propChanged.Contains("CanAssignCityZone"));
                Assert.IsTrue(propChanged.Contains("IsAssignCityZoneInvoked"));
                propChanged.Clear();

                so = ctxt.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);
            });
            EnqueueConditional(() => so.IsComplete);
            EnqueueCallback(delegate
            {
                Assert.IsFalse(so.HasError);

                Assert.IsTrue(city.CanAssignCityZone);
                Assert.IsFalse(city.IsAssignCityZoneInvoked);

                Assert.IsTrue(propChanged.Contains("CanAssignCityZone"));
                Assert.IsTrue(propChanged.Contains("IsAssignCityZoneInvoked"));
            });
            EnqueueTestComplete();
        }
        public void AddingToDomainContext()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.AutoLoad = false;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.SortDescriptors.Add(new SortDescriptor("Name", ListSortDirection.Ascending));
                this._dds.Load();
            });

            this.AssertLoadedData();

            EnqueueCallback(() =>
            {
                Assert.IsFalse(this._dds.HasChanges, "this._dds.HasChanges should be false after the initial load");
                Assert.IsFalse(context.HasChanges, "context.HasChanges should be false after the initial load");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after the initial load");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after the initial load");

                City city = new City { Name = "West Chester", StateName = "OH" };
                context.Cities.Add(city);
                Assert.AreEqual(12, context.Cities.Count, "There should be 12 items in context after adding a new city");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should remain 11 after adding a new city to the context, because it wasn't added to the ECV");
                Assert.IsTrue(context.HasChanges, "context.HasChanges should be true after adding to context");
                Assert.IsTrue(this._dds.HasChanges, "this._dds.HasChanges should be true after adding to context");
                AssertHelper.AssertSequenceSorting(this._view.Cast<City>().Select(c => c.Name), ListSortDirection.Ascending, "The cities should be sorted by name after adding the city");

                context.Cities.Remove(city);
                Assert.IsFalse(this._dds.HasChanges, "this._dds.HasChanges should be false after removing the new item");
                Assert.IsFalse(context.HasChanges, "context.HasChanges should be false after removing the new item");
                Assert.AreEqual(11, this._view.Count, "this._ecv.Count should be 11 after removing the new item");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after removing the new item");
            });

            EnqueueTestComplete();
        }
        public void LoadTwoPagesAtOnce()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.LoadSize = 4;
                this._dds.PageSize = 2;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after the initial load");
                Assert.AreEqual(4, context.Cities.Count, "context.Cities.Count should be 4 after the initial load");

                this._ddsLoadingDataExpected = 0;
                this._view.MoveToNextPage();
            });

            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 2nd page");
                Assert.AreEqual(4, context.Cities.Count, "context.Cities.Count should still be 4 after moving to the 2nd page");

                this._view.MoveToNextPage();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 3rd page");
                Assert.AreEqual(8, context.Cities.Count, "context.Cities.Count should be 8 after moving to the 3rd page");

                this._view.MoveToNextPage();
            });

            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 4th page");
                Assert.AreEqual(8, context.Cities.Count, "context.Cities.Count should be 8 after moving to the 4th page");

                this._view.MoveToNextPage();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(2, this._view.Count, "this._ecv.Count should be 2 after moving to the 5th page");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after moving to the 5th page");
            });

            EnqueueTestComplete();
        }
        public void DomainContext_Submit_DomainMethodOnly()
        {
            EntityChangeSet changeset;
            List<string> propChanged = new List<string>();
            CityDomainContext citiesProvider = new CityDomainContext(TestURIs.Cities);

            LoadOperation lo = citiesProvider.Load(citiesProvider.GetCitiesQuery(), false);
            SubmitOperation so = null;

            City firstRootCity = null;
            City lastRootCity = null;

            // wait for Load to complete, then invoke some domain methods
            EnqueueConditional(() => lo.IsComplete);
            EnqueueCallback(delegate
            {
                changeset = citiesProvider.EntityContainer.GetChanges();
                Assert.IsTrue(changeset.IsEmpty);

                // Find a root city.  This test specifically does not want to accidently use a derived type
                firstRootCity = citiesProvider.Cities.Where(c => c.GetType() == typeof(City)).FirstOrDefault();
                Assert.IsNotNull(firstRootCity, "Expected to find a root City type in entity list");

                lastRootCity = citiesProvider.Cities.Where(c => c.GetType() == typeof(City)).LastOrDefault();
                Assert.IsNotNull(lastRootCity, "Expected to find a root City type in entity list");

                Assert.AreNotEqual(firstRootCity, lastRootCity, "Expected first and last city to be different");

                firstRootCity.PropertyChanged += delegate(object sender, System.ComponentModel.PropertyChangedEventArgs e)
                {
                    bool isEntityBaseProperty = typeof(City).GetProperty(e.PropertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) == null;
                    if (!isEntityBaseProperty)
                    {
                        propChanged.Add(e.PropertyName);
                    }
                };

                Assert.IsTrue(firstRootCity.CanAssignCityZone);
                firstRootCity.AssignCityZone("Zone15");
            });

            // wait for prop changed for domain method guards
            EnqueueConditional(() => propChanged.Count > 0);
            EnqueueCallback(delegate
            {
                Assert.IsTrue(propChanged.Contains("CanAssignCityZone"));
                Assert.IsTrue(propChanged.Contains("IsAssignCityZoneInvoked"));
                Assert.IsFalse(propChanged.Contains("CanAutoAssignCityZone"));
                propChanged.Clear();

                Assert.IsTrue(lastRootCity.CanAutoAssignCityZone);
                lastRootCity.AutoAssignCityZone();

                changeset = citiesProvider.EntityContainer.GetChanges();
                Assert.AreEqual(2, changeset.ModifiedEntities.Count);

                so = citiesProvider.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);

                Assert.AreEqual(2, so.ChangeSet.ModifiedEntities.Count);
                Assert.AreEqual(0, so.ChangeSet.AddedEntities.Count);
                Assert.AreEqual(0, so.ChangeSet.RemovedEntities.Count);
            });
            // wait for submit to complete, then verify invoked entities in changeset
            EnqueueConditional(() => so.IsComplete);
            EnqueueCallback(delegate
            {
                Assert.IsNull(so.Error);
                Assert.AreEqual(2, so.ChangeSet.ModifiedEntities.Count);

                // verify we got the property change notification for the city entity as a result of autosync
                Assert.AreEqual(8, propChanged.Count);
                Assert.AreEqual(1, propChanged.Count(prop => prop == "ZoneName"));
                Assert.AreEqual(1, propChanged.Count(prop => prop == "ZoneID"));
                Assert.AreEqual(1, propChanged.Count(prop => prop == "CanAssignCityZone"));
                Assert.AreEqual(1, propChanged.Count(prop => prop == "IsAssignCityZoneInvoked"));
                Assert.AreEqual(2, propChanged.Count(prop => prop == "CanAutoAssignCityZone"));
                Assert.AreEqual(2, propChanged.Count(prop => prop == "CanAssignCityZoneIfAuthorized"));

                // verify entities are auto-synced back to the client as a result of the domain method execution on server
                Assert.AreEqual(15, citiesProvider.Cities.Single<City>(c => (c.ZoneName == "Zone15")).ZoneID);
                Assert.AreEqual(1, citiesProvider.Cities.Single<City>(c => (c.ZoneName == "Auto_Zone1")).ZoneID);

                // verify unchanged entities
                Assert.AreEqual(0, citiesProvider.Cities.First(c => (c.ZoneName == null)).ZoneID);
            });

            EnqueueTestComplete();
        }
        public void PagingPastEndTwiceCancelsSecondLoad()
        {
            CityDomainContext context = new CityDomainContext();
            int pageSize = 6;
            int cityCount = new CityData().Cities.Count;
            int lastPageIndex = (cityCount / pageSize) - ((cityCount % pageSize == 0) ? 1 : 0);

            EnqueueCallback(() =>
            {
                this._dds.PageSize = pageSize;
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                // We need to make sure the second load caused by paging past the last page is cancelable.
                // To do this, we'll load 4 times. The first is caused by moving past the last page. The second
                // is automatically started when the first load does not return any entities and shifts back to
                // the last page. The third and fourth move past and back again and are started such that the
                // third load cancels the second.
                this._dds.LoadingData += (sender, e) =>
                {
                    // We only want to reload once to cancel the second load attempt
                    if (this._ddsLoadingData == 2)
                    {
                        this._view.MoveToPage(lastPageIndex + 2);
                    }
                };
                this._dds.LoadedData += (sender, e) =>
                {
                    Assert.IsTrue((this._ddsLoadedData == 2) == e.Cancelled,
                        "Only the second load should have been canceled.");
                };

                this._view.MoveToPage(lastPageIndex + 1);
            });

            this.AssertLoadingData(4);

            EnqueueTestComplete();
        }
        public void DomainContext_Submit_DomainMethodAndCRUD()
        {
            List<string> propChanged_addedCity = new List<string>();
            City newCity = new City { Name = "Sammamish", CountyName = "King", StateName = "WA" };
            int refZipCode = 0;
            int refCityCount = 0;

            CityDomainContext citiesProvider = new CityDomainContext(TestURIs.Cities);

            LoadOperation lo = citiesProvider.Load(citiesProvider.GetCitiesQuery(), false);
            SubmitOperation so = null;

            // wait for LoadCities to complete, then LoadZips
            EnqueueConditional(() => lo.IsComplete);
            EnqueueCallback(delegate
            {
                refCityCount = citiesProvider.Cities.Count;
                lo = citiesProvider.Load(citiesProvider.GetZipsQuery(), false);
            });

            // wait for Load to complete, then invoke some domain methods
            EnqueueConditional(() => lo.IsComplete);
            EnqueueCallback(delegate
            {
                // this test the following combinations of CRUD and Domain method in changeset:
                // - Invoke -> update
                // - Add -> invoke
                // - Remove
                // - Invoke only
                City[] cities = citiesProvider.Cities.ToArray();
                cities[0].ZoneName = "Zone44";
                cities[0].AssignCityZone("Zone1");
                cities[1].AssignCityZone("Zone2");
                citiesProvider.Cities.Add(newCity);
                newCity.AssignCityZone("Zone3");
                citiesProvider.Cities.Remove(cities[4]);
                citiesProvider.Cities.Remove(cities[5]);

                // keep a reference zip code before invoking the method: this will increment Code by offset=1 on the server
                Zip zip = citiesProvider.Zips.First();
                refZipCode = zip.Code;
                zip.ReassignZipCode(1, true);

                newCity.PropertyChanged += delegate(object sender, System.ComponentModel.PropertyChangedEventArgs e)
                {
                    if (e.PropertyName != "IsReadOnly" && e.PropertyName != "HasChanges"
                        && e.PropertyName != "EntityState" && e.PropertyName != "ValidationErrors")
                    {
                        propChanged_addedCity.Add(e.PropertyName);
                    }
                };

                Assert.IsTrue(newCity.CanAssignCityZoneIfAuthorized);
                Assert.IsTrue(newCity.CanAutoAssignCityZone);

                so = citiesProvider.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);

                Assert.IsFalse(newCity.CanAssignCityZoneIfAuthorized);
                Assert.IsFalse(newCity.CanAutoAssignCityZone);

                Assert.AreEqual(3, so.ChangeSet.ModifiedEntities.Count);
                Assert.AreEqual(1, so.ChangeSet.AddedEntities.Count);
                Assert.AreEqual(2, so.ChangeSet.RemovedEntities.Count);
            });
            EnqueueConditional(() => so.IsComplete);
            EnqueueCallback(delegate
            {
                Assert.IsNull(so.Error, string.Format("SubmitOperation.Error should be null.\r\nMessage: {0}\r\nStack Trace:\r\n{1}", so.Error != null ? so.Error.Message : string.Empty, so.Error != null ? so.Error.StackTrace : string.Empty));
                Assert.IsTrue(newCity.CanAssignCityZoneIfAuthorized);
                Assert.IsTrue(newCity.CanAutoAssignCityZone);
                Assert.IsTrue(newCity.CanAssignCityZone);

                // verify we got property change notifications for the new city entity (guard property should be reverted once SubmitChanges is called)
                Assert.AreEqual(9, propChanged_addedCity.Count);
                Assert.AreEqual(1, propChanged_addedCity.Count(prop => prop == "ZoneName"));
                Assert.AreEqual(1, propChanged_addedCity.Count(prop => prop == "ZoneID"));
                Assert.AreEqual(1, propChanged_addedCity.Count(prop => prop == "CanAssignCityZone"));
                Assert.AreEqual(1, propChanged_addedCity.Count(prop => prop == "IsAssignCityZoneInvoked"));
                // The other custom method invocations should have changed from true -> false during submit
                // and from false -> true after submit
                Assert.AreEqual(2, propChanged_addedCity.Count(prop => prop == "CanAssignCityZoneIfAuthorized"));
                Assert.AreEqual(2, propChanged_addedCity.Count(prop => prop == "CanAutoAssignCityZone"));


                // verify entities are auto-synced back to the client as a result of the domain method execution on server
                Assert.AreEqual(1, citiesProvider.Cities.Single<City>(c => (c.ZoneName == "Zone1" && c.CountyName == "King")).ZoneID);
                Assert.AreEqual(2, citiesProvider.Cities.Single<City>(c => (c.ZoneName == "Zone2")).ZoneID);
                Assert.AreEqual(3, citiesProvider.Cities.Single<City>(c => (c.ZoneName == "Zone3" && c.Name == newCity.Name)).ZoneID);
                Assert.IsTrue(citiesProvider.Zips.Any<Zip>(z => z.Code == refZipCode - 1));

                // verify unchanged entities
                Assert.IsFalse(citiesProvider.Cities.Any(c => (c.ZoneName == null && c.ZoneID != 0)));

                // verify that after a successful submit, DM invocations on the entities have been accepted
                Assert.IsFalse(so.ChangeSet.ModifiedEntities.Any(p => p.EntityActions.Any()));
                EntityChangeSet changeSet = citiesProvider.EntityContainer.GetChanges();
                Assert.IsTrue(changeSet.IsEmpty);
            });

            EnqueueTestComplete();
        }
        public void PagingLargePageSize()
        {
            CityDomainContext context = new CityDomainContext();

            EnqueueCallback(() =>
            {
                this._dds.QueryName = "GetCitiesQuery";
                this._dds.DomainContext = context;
                this._dds.LoadSize = 5;
                this._dds.PageSize = 10;
                this._dds.Load();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(10, this._pagedCollectionView.ItemCount, "ItemCount should be 10 after initial load");
                Assert.AreEqual(10, this._view.Count, "Count should be 10 after initial load");

                this._view.MoveToNextPage();
            });

            this.AssertLoadingData();
            this.AssertPageChanged();

            EnqueueCallback(() =>
            {
                this.ResetLoadState();
                this.ResetPageChanged();

                Assert.AreEqual(11, this._pagedCollectionView.ItemCount, "ItemCount should be 11 after moving to the 2nd page");
                Assert.AreEqual(1, this._view.Count, "Count should be 1 after moving to the 2nd page");
                Assert.AreEqual(11, context.Cities.Count, "context.Cities.Count should be 11 after moving to the 2nd page");
            });

            EnqueueTestComplete();
        }
        public void DomainMethod_InvalidParameterTypes_Bug615860()
        {
            // Create a test City Entity
            CityDomainContext provider = new CityDomainContext(TestURIs.Cities);
            City city = new City();
            city.Name = "TestCity";
            city.StateName = "AA";
            provider.Cities.Add(city); // attach to set entity set reference

            // Invoke a domain method with correct number of parameters but incorrect types
            ExceptionHelper.ExpectException<MissingMethodException>(
                () => city.InvokeAction("AssignCityZone", 1 /*correct parameter type is string*/),
                string.Format(Resource.ValidationUtilities_MethodNotFound, "Cities.City", "AssignCityZone", 1, "'System.Int32'"));
        }