public void GetErrorDescription()
        {
            var simpleConceptInfo = new SimpleConceptInfo {
                Name = "s", Data = "d"
            };
            var refConceptInfo = new RefConceptInfo {
                Name = "r", Reference = simpleConceptInfo
            };
            var refRefConceptInfo = new RefRefConceptInfo {
                Name = "rr", Reference = refConceptInfo
            };

            Assert.AreEqual("Rhetos.Dsl.Test.ConceptInfoHelperTest+RefRefConceptInfo Name=rr Reference=r.s", refRefConceptInfo.GetErrorDescription());

            refRefConceptInfo.Name = null;
            Assert.AreEqual("Rhetos.Dsl.Test.ConceptInfoHelperTest+RefRefConceptInfo Name=<null> Reference=r.s", refRefConceptInfo.GetErrorDescription());
            refRefConceptInfo.Name = "rr";

            refRefConceptInfo.Reference = null;
            Assert.AreEqual("Rhetos.Dsl.Test.ConceptInfoHelperTest+RefRefConceptInfo Name=rr Reference=<null>", refRefConceptInfo.GetErrorDescription());
            refRefConceptInfo.Reference = refConceptInfo;

            simpleConceptInfo.Name = null;
            TestUtility.AssertContains(refRefConceptInfo.GetErrorDescription(),
                                       new[] { refRefConceptInfo.GetType().FullName, "Name=rr", "Reference=", "null" });
            simpleConceptInfo.Name = "s";

            Assert.AreEqual("<null>", ConceptInfoHelper.GetErrorDescription(null));

            Assert.AreEqual(typeof(SimpleConceptInfo).FullName + " Name=s Data=<null>", new SimpleConceptInfo {
                Name = "s", Data = null
            }.GetErrorDescription());
        }
        public void LoadPreviouslyAppliedConceptsTest_DuplicateAppliedConcepts()
        {
            try
            {
                var ca1 = MockSqlExecuter.ConceptApplication;
                var ca2 = MockSqlExecuter.ConceptApplicationCopy;
                Assert.AreEqual(ca1.GetConceptApplicationKey(), ca2.GetConceptApplicationKey());
                var expected = new[] { ca1, ca2 };

                var conceptApplicationRepository = TestConceptApplicationRepository(expected);
                var appliedConcepts = conceptApplicationRepository.Load();
                Assert.IsNotNull(appliedConcepts);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                TestUtility.AssertContains(ex.Message, MockSqlExecuter.ConceptApplication.GetConceptApplicationKey());
                TestUtility.AssertContains(ex.Message, new[] {
                    SqlUtility.GuidToString(MockSqlExecuter.ConceptApplication.Id),
                    SqlUtility.GuidToString(MockSqlExecuter.ConceptApplicationCopy.Id)
                });

                throw;
            }
        }
Example #3
0
        public void CreateList()
        {
            int queryCount = 0;
            var source = new[] { 11, 12, 13 }.Select(x => { queryCount++; return(x); });

            var repos = NewSimpleRepos();

            Assert.AreEqual(0, queryCount);
            var list1 = repos.CreateList(source, (sourceItem, newItem) => { newItem.Name = sourceItem.ToString(); });

            Assert.AreEqual(3, queryCount, "CreateList should query the source only once.");

            var list2    = repos.CreateList(2);
            int nextName = 101;

            foreach (var item in list2)
            {
                item.Name = (nextName++).ToString();
            }

            Assert.AreEqual("11, 12, 13", TestUtility.DumpSorted(list1));
            Assert.AreEqual("101, 102", TestUtility.DumpSorted(list2));

            string expectedType = typeof(List <SimpleEntity>).FullName;

            TestUtility.AssertContains(list1.GetType().FullName, expectedType, "Instance should be a list of the entity type, not a list of interfaces.");
        }
Example #4
0
        public void StopImpersonating_EmptyUser()
        {
            var initialUser = new FakeUserInfo("InitialUser");               // User than started the impersonation.
            var currentlyAuthenticatedUser = new FakeUserInfo("", "", true); // Unexpected authentication context, similar to anonymous user. Testing for robust impersonation management.
            var impersonateUserName        = "******";
            var initialCookie = ImpersonationServiceHelper.SetImpersonation(initialUser, impersonateUserName);

            // Stopping impersonation should expire the impersonation cookie, even if the authentication context is invalid:

            var removeResponse = ImpersonationServiceHelper.RemoveImpersonation(currentlyAuthenticatedUser, initialCookie);

            AssertIsBefore(removeResponse.ResponseCookie.Options.Expires.Value, DateTimeOffset.Now.AddSeconds(-1));
            Assert.AreEqual(ImpersonationService.CookieKey, removeResponse.ResponseCookie.Key);
            Assert.AreEqual(" as ",
                            ReportImpersonationInfo(ImpersonationServiceHelper.DecryptCookieValue(removeResponse.ResponseCookie.Value))); // No need for impersonation data in the cookie.
            TestUtility.AssertContains(
                string.Join(Environment.NewLine, removeResponse.Log),
                "Removing impersonation, the original user is no longer authenticated.");

            // Next request with expired cookie should be without impersonation, even if the expired cookie is sent again.

            var authResponseAfterRemove = ImpersonationServiceHelper.GetAuthenticationInfo(currentlyAuthenticatedUser, removeResponse.ResponseCookie);

            Assert.AreEqual(
                "No impersonation, original not recognized",
                ReportImpersonationStatus(authResponseAfterRemove.AuthenticationInfo));
        }
Example #5
0
        public void StopImpersonating()
        {
            var initialUser         = new FakeUserInfo("TestUser");
            var impersonateUserName = "******";
            var initialCookie       = ImpersonationServiceHelper.SetImpersonation(initialUser, impersonateUserName);

            // Review test setup:

            Assert.AreEqual(
                "TestUser as TestImpersonatedUser, original TestUser",
                ReportImpersonationStatus(ImpersonationServiceHelper.GetAuthenticationInfo(initialUser, initialCookie).AuthenticationInfo));

            // Stopping impersonation should expire the impersonation cookie:

            (var responseCookie, var log) = ImpersonationServiceHelper.RemoveImpersonation(initialUser, initialCookie);

            AssertIsBefore(responseCookie.Options.Expires.Value, DateTimeOffset.Now.AddSeconds(-1));
            Assert.AreEqual(ImpersonationService.CookieKey, responseCookie.Key);
            Assert.AreEqual(" as ",
                            ReportImpersonationInfo(ImpersonationServiceHelper.DecryptCookieValue(responseCookie.Value))); // No need for impersonation data in the cookie.

            TestUtility.AssertContains(
                string.Join(Environment.NewLine, log),
                "StopImpersonating: TestUser as TestImpersonatedUser");

            // Next request with expired cookie should be without impersonation, even if the expired cookie is sent again.

            Assert.AreEqual(
                "No impersonation, original TestUser",
                ReportImpersonationStatus(ImpersonationServiceHelper.GetAuthenticationInfo(initialUser, responseCookie).AuthenticationInfo));
        }
Example #6
0
        public void Dependant_FKConstraintDelete()
        {
            using (var container = new RhetosTestContainer())
            {
                var repository = container.Resolve <Common.DomRepository>();

                var s1 = new TestPolymorphic.Simple1 {
                    ID = Guid.NewGuid(), Name = "a", Days = 1
                };
                repository.TestPolymorphic.Simple1.Insert(new[] { s1 });

                var dep = new TestPolymorphic.Dependant {
                    ID = Guid.NewGuid(), Name = "dep", SimpleBaseID = s1.ID
                };
                repository.TestPolymorphic.Dependant.Insert(new[] { dep });
                Assert.AreEqual("dep-a", TestUtility.DumpSorted(
                                    repository.TestPolymorphic.DependantBrowse.Query(new[] { dep.ID }),
                                    item => item.Name + "-" + item.SimpleBaseName));

                var ex = TestUtility.ShouldFail <Rhetos.UserException>(
                    () => repository.TestPolymorphic.Simple1.Delete(new[] { s1 }),
                    "It is not allowed to delete");
                TestUtility.AssertContains(ex.ToString(), new[] { "Dependant", "REFERENCE", "SimpleBase" }, "Expected inner SQL exception");
            }
        }
Example #7
0
        public void Dependant_FKConstraintDeleteUniqueReferenced()
        {
            using (var container = new RhetosTestContainer())
            {
                var repository = container.Resolve <Common.DomRepository>();

                var s1 = new TestPolymorphic.Simple1 {
                    Name = "s1", Days = 1
                };
                repository.TestPolymorphic.Simple1.Insert(new[] { s1 });

                var d1 = new TestPolymorphic.DependantUniqueReference {
                    Name = "d1", ID = s1.ID
                };
                repository.TestPolymorphic.DependantUniqueReference.Insert(new[] { d1 });

                Assert.AreEqual("s1-d1", TestUtility.DumpSorted(
                                    repository.TestPolymorphic.SimpleBase.Query(new[] { d1.ID }),
                                    item => item.Name + "-" + item.Extension_DependantUniqueReference.Name));

                var ex = TestUtility.ShouldFail <Rhetos.UserException>(
                    () => repository.TestPolymorphic.Simple1.Delete(new[] { s1 }),
                    "It is not allowed to delete");
                TestUtility.AssertContains(ex.ToString(), new[] { "DependantUniqueReference", "REFERENCE", "SimpleBase" }, "Expected inner SQL exception");
            }
        }
Example #8
0
        public void ParallelInsertsLockErrorHandling()
        {
            var actions = new Action <Common.ExecutionContext>[]
            {
                // Starts at 0 ms, ends at 400ms.
                context =>
                {
                    Thread.Sleep(0);
                    context.SqlExecuter.ExecuteSql("SET LOCK_TIMEOUT 0");
                    context.Repository.TestAutoCode.Simple.Insert(new TestAutoCode.Simple {
                        Code = "+"
                    });
                    Thread.Sleep(400);
                },
                // Starts at 100 ms, lock timeout at 300ms.
                context =>
                {
                    Thread.Sleep(100);
                    context.SqlExecuter.ExecuteSql("SET LOCK_TIMEOUT 200");
                    context.Repository.TestAutoCode.Simple.Insert(new TestAutoCode.Simple {
                        Code = "+"
                    });
                },

                // Starts at 200 ms, lock timeout at 200ms.
                context =>
                {
                    Thread.Sleep(200);
                    context.SqlExecuter.ExecuteSql("SET LOCK_TIMEOUT 0");
                    context.Repository.TestAutoCode.Simple.Insert(new TestAutoCode.Simple {
                        Code = "+"
                    });
                },

                // Starts at 200 ms, ends at 200ms.
                context =>
                {
                    Thread.Sleep(200);
                    context.SqlExecuter.ExecuteSql("SET LOCK_TIMEOUT 0");
                    context.Repository.TestAutoCode.Simple.Load(item => item.Code == "1");
                }
            };

            var exceptions = ExecuteParallel(actions,
                                             context => context.Repository.TestAutoCode.Simple.Insert(new TestAutoCode.Simple {
                Code = "1"
            }),
                                             context => Assert.AreEqual(1, context.Repository.TestAutoCode.Simple.Query().Count()));

            Assert.IsNull(exceptions[0]);
            Assert.IsNotNull(exceptions[1]);
            Assert.IsNotNull(exceptions[2]);
            Assert.IsNull(exceptions[3]); // sql3 should be allowed to read the record with code '1'. sql0 has exclusive lock on code '2'. autocode should not put exclusive lock on other records.

            // Query sql1 may generate next autocode, but it should wait for the entity's table exclusive lock to be released (from sql0).
            TestUtility.AssertContains(exceptions[1].ToString(), new[] { "Cannot insert", "another user's insert command is still running", "TestAutoCode.Simple" });

            // Query sql2 may not generate next autocode until sql1 releases the lock.
            TestUtility.AssertContains(exceptions[2].ToString(), new[] { "Cannot insert", "another user's insert command is still running", "TestAutoCode.Simple" });
        }
Example #9
0
        public void InsertAndThrowException()
        {
            var item1ID = Guid.NewGuid();
            var item2ID = Guid.NewGuid();

            using (var container = new RhetosTestContainer(true))
            {
                var repository = container.Resolve <Common.DomRepository>();
                repository.TestAction.ToInsert.Insert(new TestAction.ToInsert {
                    ID = item1ID
                });

                var exception = TestUtility.ShouldFail <ApplicationException>(
                    () => repository.TestAction.InsertAndThrowException.Execute(new TestAction.InsertAndThrowException {
                    Message = "abcd", ItmemID = item2ID
                }),
                    "abcd");
                var exceptionOrigin = exception.StackTrace.Substring(0, exception.StackTrace.IndexOf(Environment.NewLine));
                TestUtility.AssertContains(exceptionOrigin, new[] { "InsertAndThrowException_Repository", "Execute", "InsertAndThrowException parameters" });
            }

            using (var container = new RhetosTestContainer())
            {
                var repository          = container.Resolve <Common.DomRepository>();
                var toInsertEntityCount = repository.TestAction.ToInsert.Query(x => x.ID == item1ID || x.ID == item2ID).Count();
                Assert.AreEqual(0, toInsertEntityCount);
            }
        }
Example #10
0
        public void Dependant_FKConstraintInsert()
        {
            using (var container = new RhetosTestContainer())
            {
                var repository = container.Resolve <Common.DomRepository>();

                var s1 = new TestPolymorphic.Simple1 {
                    Name = "a", Days = 1
                };
                repository.TestPolymorphic.Simple1.Insert(new[] { s1 });

                var dep = new TestPolymorphic.Dependant {
                    Name = "dep", SimpleBaseID = s1.ID
                };
                repository.TestPolymorphic.Dependant.Insert(new[] { dep });

                var depInvalidReference = new TestPolymorphic.Dependant {
                    Name = "depInvalidReference", SimpleBaseID = Guid.NewGuid()
                };
                var ex = TestUtility.ShouldFail <Rhetos.UserException>(
                    () => repository.TestPolymorphic.Dependant.Insert(new[] { depInvalidReference }),
                    "It is not allowed to enter the record.");
                TestUtility.AssertContains(ex.ToString(), new[] { "Dependant", "FOREIGN KEY", "SimpleBase" }, "Expected inner SQL exception");
            }
        }
        public void MaskPasswordTest()
        {
            var tests = new ListOfTuples <string, string[]>
            {
                // Format: connection string, expected content.
                { "Server=tcp:name.database.windows.net,1433;Initial Catalog=RhetosAzureDB;Persist Security Info=False;User ID=jjj;Password=jjj;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;",
                  new[] { "tcp:name.database.windows.net,1433", "RhetosAzureDB" } },
                { "Data Source=localhost;Initial Catalog=Rhetos;Integrated Security=SSPI;",
                  new[] { "localhost", "Rhetos" } },
                { "User Id=jjj;Password=jjj;Data Source=localhost:1521/xe;",
                  new[] { "localhost:1521/xe" } },
                { "User Id=jjj;Password='******';Data Source=localhost:1521/xe;",
                  new[] { "localhost:1521/xe" } },
                { "User Id=jjj;Password=\"jjj;jjj=jjj\";Data Source=localhost:1521/xe;",
                  new[] { "localhost:1521/xe" } },
                { "';[]=-",
                  Array.Empty <string>() },
            };

            foreach (var test in tests)
            {
                Console.WriteLine(test.Item1);
                string report = SqlUtility.SqlConnectionInfo(test.Item1);
                Console.WriteLine("=> " + report);

                TestUtility.AssertNotContains(report, "j", "Username or password leaked.");
                if (test.Item2.Any())
                {
                    TestUtility.AssertContains(report, test.Item2);
                }
            }
        }
Example #12
0
            public void Insert(string s, int i, TestUnique.R r, bool shouldFail = false)
            {
                string error   = null;
                var    newItem = new TestUnique.Multi {
                    S = s, I = i, RID = r.ID, ID = Guid.NewGuid()
                };

                try
                {
                    Console.WriteLine("Inserting " + s + ", " + i + " ...");
                    _repository.TestUnique.Multi.Insert(new[] { newItem });
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
                    error = ex.Message;
                    if (!shouldFail)
                    {
                        throw;
                    }
                }
                if (shouldFail)
                {
                    Assert.IsNotNull(error, "Insert should have failed with an exception.");
                    TestUtility.AssertContains(error, "Cannot insert duplicate key");
                }
            }
Example #13
0
        public void StopImpersonating_DifferentUser()
        {
            var initialUser = new FakeUserInfo("InitialUser");                // User than started the impersonation.
            var currentlyAuthenticatedUser = new FakeUserInfo("CurrentUser"); // Currently authenticated user does not match the initial user, so the impersonation cookie is invalid.
            var impersonateUserName        = "******";
            var initialCookie = ImpersonationServiceHelper.SetImpersonation(initialUser, impersonateUserName);

            // Stopping impersonation should expire the impersonation cookie, even if the authentication context is invalid:

            var removeResponse = ImpersonationServiceHelper.RemoveImpersonation(currentlyAuthenticatedUser, initialCookie);

            AssertIsBefore(removeResponse.ResponseCookie.Options.Expires.Value, DateTimeOffset.Now.AddSeconds(-1));
            Assert.AreEqual(ImpersonationService.CookieKey, removeResponse.ResponseCookie.Key);
            Assert.AreEqual(" as ",
                            ReportImpersonationInfo(ImpersonationServiceHelper.DecryptCookieValue(removeResponse.ResponseCookie.Value))); // No need for impersonation data in the cookie.
            TestUtility.AssertContains(
                string.Join(Environment.NewLine, removeResponse.Log),
                "Removing impersonation, the current authentication context (CurrentUser) does not match the initial one (InitialUser).");

            // Next request with expired cookie should be without impersonation, even if the expired cookie is sent again.

            var authResponseAfterRemove = ImpersonationServiceHelper.GetAuthenticationInfo(currentlyAuthenticatedUser, removeResponse.ResponseCookie);

            Assert.AreEqual(
                "No impersonation, original CurrentUser",
                ReportImpersonationStatus(authResponseAfterRemove.AuthenticationInfo));
            Assert.IsNull(authResponseAfterRemove.ResponseCookie, "There is no need to send the expired cookie again, client already has the expired one.");
        }
Example #14
0
        public void InsertOrUpdateOrDeleteOrDeactivate_LoadFilter()
        {
            var oldItems = new DeacEntityList {
                { "a1", true }, { "a2", true }, { "a3", true },
                { "d1", false }, { "d2", false }, { "d3", false },
                { "o1", null }, { "o2", true }, { "o3", false },
                { "c1", null }, { "c2", null }, { "c3", true }, { "c4", false },
            };

            var newItems = new DeacEntityList {
                { "a1", null }, { "a2", true }, { "a3", false },
                { "d1", null }, { "d2", true }, { "d3", false },
                { "n1", null }, { "n2", true }, { "n3", false },
                { "c1", true }, { "c2", false }, { "c3", false }, { "c4", true },
            };

            var hideOldItems = new[] { "a1", "d1", "o1", "c1", "c2" };

            var repos = new TestGenericRepository <IDeacEntity, DeacEntity>(oldItems);

            repos.InsertOrUpdateOrDeleteOrDeactivate(newItems, new DeacCompareName(), DeacCompareNameValue,
                                                     (Expression <Func <IDeacEntity, bool> >)(item => !hideOldItems.Contains(item.Name)),
                                                     (dest, src) => { dest.Name = src.Name; dest.Active = src.Active; },
                                                     new FilterAll());

            Assert.AreEqual("UPDATE a3 False, c3 False, c4 True, d2 True, o2 False, INSERT a1 True, c1 True, c2 False, d1 True, n1 True, n2 True, n3 False",
                            repos.RepositoryMock.Log.ToString());

            TestUtility.AssertContains(repos.RepositoryMock.InsertedGroups.Single().GetType().FullName,
                                       "System.Collections.Generic.List`1[[Rhetos.CommonConcepts.Test.GenericRepositoryWriteTest+DeacEntity",
                                       "GenericRepository should prepare native type for saving to the entity's repository.");
            TestUtility.AssertContains(repos.RepositoryMock.UpdatedGroups.Single().GetType().FullName,
                                       "System.Collections.Generic.List`1[[Rhetos.CommonConcepts.Test.GenericRepositoryWriteTest+DeacEntity",
                                       "GenericRepository should prepare native type for saving to the entity's repository.");
        }
Example #15
0
        void TestError(Action action, string errorMessage, string locationFunctionName)
        {
            var ex = TestUtility.ShouldFail <ApplicationException>(action, errorMessage);

            string errorLocation = "at " + typeof(ErrorRepository).FullName.Replace("+", ".") + "." + locationFunctionName + "(";

            TestUtility.AssertContains(ex.ToString(), errorLocation);
        }
Example #16
0
        public void ParsePosition()
        {
            var simpleParser     = new GenericParserHelper <SimpleConceptInfo>("abc");
            var tokenReader      = TestTokenReader("simple abc def", 1);
            SimpleConceptInfo ci = (SimpleConceptInfo)simpleParser.Parse(tokenReader, new Stack <IConceptInfo>()).Value;

            Assert.AreEqual("def", ci.Name);
            TestUtility.AssertContains(tokenReader.ReportPosition(), "column 15,");
        }
        public void CorrectBuildOptions()
        {
            var configuration = RhetosHostTestBuilder.GetBuildConfiguration();

            Assert.AreEqual("TestValue", configuration.GetValue <string>("TestBuildSettings"));
            var connectionsString = configuration.GetValue <string>($"ConnectionStrings:RhetosConnectionString");

            TestUtility.AssertContains(connectionsString, new[] { "TestSql", "TestDb" });
        }
Example #18
0
        public void ParsePosition()
        {
            var simpleParser     = new GenericParserHelper <SimpleConceptInfo>("abc");
            var tokenReader      = TestTokenReader("simple abc def", 1);
            var node             = simpleParser.GenericParser.Parse(tokenReader, new Stack <ConceptSyntaxNode>(), out var warnings).Value;
            SimpleConceptInfo ci = (SimpleConceptInfo)ConceptInfoHelper.ConvertNodeToConceptInfo(node);

            Assert.AreEqual("def", ci.Name);
            TestUtility.AssertContains(tokenReader.ReportPosition(), "column 15,");
        }
Example #19
0
 public void NullArgument()
 {
     using (var container = new RhetosTestContainer(false))
     {
         var repository = container.Resolve <Common.DomRepository>();
         var ex         = TestUtility.ShouldFail(
             () => repository.TestFullTextSearch.Simple_Search.Query()
             .Where(item => DatabaseExtensionFunctions.FullTextSearch(item.ID, null, "TestFullTextSearch.Simple_Search", "*"))
             .Select(item => item.Base.Name).ToList());
         TestUtility.AssertContains(ex.ToString(), "Search pattern must not be NULL.");
     }
 }
Example #20
0
        public void ReportPositionTest()
        {
            var dslScript = new DslScript {
                Name = "name1", Script = "abc", Path = "name1"
            };

            TestUtility.ShouldFail(() => dslScript.ReportPosition(-1), "out of range", "-1"); // Index too low
            TestUtility.AssertContains(dslScript.ReportPosition(0), "before: \"abc\"", "name1");
            TestUtility.AssertContains(dslScript.ReportPosition(1), "before: \"bc\"", "name1");
            TestUtility.AssertContains(dslScript.ReportPosition(2), "before: \"c\"", "name1");
            TestUtility.AssertContains(dslScript.ReportPosition(3), "before: \"\"", "name1");
            TestUtility.ShouldFail(() => dslScript.ReportPosition(4), "out of range", "4"); // Invalid position not in any script
        }
Example #21
0
 public void ColumnsParameter()
 {
     using (var container = new RhetosTestContainer(false))
     {
         var    repository = container.Resolve <Common.DomRepository>();
         string columns    = "*";
         var    ex         = TestUtility.ShouldFail(
             () => repository.TestFullTextSearch.Simple_Search.Query()
             .Where(item => DatabaseExtensionFunctions.FullTextSearch(item.ID, "a", "TestFullTextSearch.Simple_Search", columns))
             .Select(item => item.Base.Name).ToList());
         TestUtility.AssertContains(ex.ToString(), new[] { "Please use a string literal", "searchColumns" });
     }
 }
Example #22
0
        public void DeleteIntegerStringDataTime()
        {
            using (var container = new RhetosTestContainer())
            {
                var repository = container.Resolve <Common.DomRepository>();

                var newItem = new TestLogging.Simple {
                    ID = Guid.NewGuid(), Count = -2, Name = "abc", Created = DateTime.Now
                };
                repository.TestLogging.Simple.Insert(new[] { newItem });

                var logRecord = repository.Common.Log.Query().Where(log => log.ItemId == newItem.ID && log.Action == "Insert").SingleOrDefault();
                Assert.IsNotNull(logRecord, "There should be 'Insert' record in the log.");
                Assert.AreEqual("", logRecord.Description);

                repository.TestLogging.Simple.Delete(new[] { newItem });

                logRecord = repository.Common.Log.Query().Where(log => log.ItemId == newItem.ID && log.Action == "Delete").SingleOrDefault();
                Assert.IsNotNull(logRecord, "There should be 'Delete' record in the log.");

                Assert.AreEqual(SqlUtility.UserContextInfoText(container.Resolve <IUserInfo>()), logRecord.ContextInfo);
                Assert.IsTrue(container.Resolve <IUserInfo>().IsUserRecognized);
                TestUtility.AssertContains(logRecord.ContextInfo, container.Resolve <IUserInfo>().UserName);
                TestUtility.AssertContains(logRecord.ContextInfo, container.Resolve <IUserInfo>().Workstation);

                var now = SqlUtility.GetDatabaseTime(container.Resolve <ISqlExecuter>());
                Assert.IsTrue(logRecord.Created.Value.Subtract(now).TotalSeconds < 5);

                Assert.AreEqual("TestLogging.Simple", logRecord.TableName);

                Assert.IsTrue(!string.IsNullOrWhiteSpace(logRecord.UserName));
                Assert.IsTrue(!string.IsNullOrWhiteSpace(logRecord.Workstation));

                // Description is XML:
                var xmlText = @"<?xml version=""1.0"" encoding=""UTF-16""?>" + Environment.NewLine + logRecord.Description;
                Console.WriteLine(xmlText);
                var xdoc = XDocument.Parse(xmlText);
                Console.WriteLine(string.Join(", ", xdoc.Root.Attributes().Select(a => a.Name + ":" + a.Value)));

                var logCount = int.Parse(xdoc.Root.Attribute("Count").Value);
                Assert.AreEqual(newItem.Count, logCount);

                var logName = xdoc.Root.Attribute("Name").Value;
                Assert.AreEqual(newItem.Name, logName);

                var logCreated = DateTime.Parse(xdoc.Root.Attribute("Created").Value);
                Assert.IsTrue(Math.Abs(newItem.Created.Value.Subtract(logCreated).TotalMilliseconds) <= 1000, "Error made by converting DataTime to XML should be less than a second.");
            }
        }
Example #23
0
        public void ColumnsParameter()
        {
            // SQL Server does not support the columns parameter to be a variable.

            using (var scope = TestScope.Create())
            {
                var    repository = scope.Resolve <Common.DomRepository>();
                string columns    = "*";
                var    ex         = TestUtility.ShouldFail(
                    () => repository.TestFullTextSearch.SimpleFTS.Query()
                    .Where(item => DatabaseExtensionFunctions.FullTextSearch(item.ID, "a", "TestFullTextSearch.SimpleFTS", columns))
                    .Select(item => item.Base.Name).ToList());
                TestUtility.AssertContains(ex.ToString(), new[] { "Please use a string literal", "searchColumns" });
            }
        }
Example #24
0
        public void TableParameter()
        {
            // SQL Server does not support the table parameter to be a variable.

            using (var container = new RhetosTestContainer(false))
            {
                var    repository = container.Resolve <Common.DomRepository>();
                string table      = "TestFullTextSearch.SimpleFTS";
                var    ex         = TestUtility.ShouldFail(
                    () => repository.TestFullTextSearch.SimpleFTS.Query()
                    .Where(item => DatabaseExtensionFunctions.FullTextSearch(item.ID, "a", table, "*"))
                    .Select(item => item.Base.Name).ToList());
                TestUtility.AssertContains(ex.ToString(), new[] { "Please use a string literal", "tableName" });
            }
        }
Example #25
0
        public void RankTopParameter()
        {
            // SQL Server does not support the rankTop parameter to be an expression.

            using (var container = new RhetosTestContainer(false))
            {
                var repository = container.Resolve <Common.DomRepository>();
                int topValue   = 10;
                var ex         = TestUtility.ShouldFail(
                    () => repository.TestFullTextSearch.SimpleFTS.Query()
                    .Where(item => DatabaseExtensionFunctions.FullTextSearch(item.ID, "a", "TestFullTextSearch.SimpleFTS", "*", topValue + 1))
                    .Select(item => item.Base.Name).ToList());
                TestUtility.AssertContains(ex.ToString(), new[] { "Please use a simple integer variable", "rankTop" });
            }
        }
        public void LogCommandClientErrorDescription()
        {
            var log = new List <string>();

            using (var scope = TestScope.Create(builder => builder
                                                .ConfigureLogMonitor(log)
                                                .ConfigureIgnoreClaims()))
            {
                var processingEngine = scope.Resolve <IProcessingEngine>();
                var saveDuplicates   = new SaveEntityCommandInfo
                {
                    Entity       = "TestUnique.E",
                    DataToInsert = new[]
                    {
                        new TestUnique.E {
                            I = 123, S = "abc"
                        },
                        new TestUnique.E {
                            I = 123, S = "abc"
                        },
                    }
                };
                var processingEngineResult = processingEngine.Execute(new[] { saveDuplicates });
                Assert.IsFalse(processingEngineResult.Success);
                TestUtility.AssertContains(processingEngineResult.UserMessage, "duplicate");

                var excected = new ListOfTuples <string, IEnumerable <string> >()
                {
                    { "request info", new[] { "ProcessingEngine Request", "SaveEntityCommandInfo TestUnique.E, insert 2" } },
                    { "command xml", new[] { "ProcessingEngine Commands", "<DataToInsert", ">abc</S>" } },
                    { "error info", new[] { "Command failed: SaveEntityCommandInfo TestUnique.E, insert 2. Rhetos.UserException", "duplicate", "IX_E_S_I_R", "stack trace" } },
                    { "CommandsWithClientError xml", new[] { "ProcessingEngine CommandsWithClientError", "<DataToInsert", ">abc</S>" } },
                    { "CommandsWithClientError result", new[] { "ProcessingEngine CommandsWithClientError", "<UserMessage>", "It is not allowed" } },
                };

                foreach (var test in excected)
                {
                    Assert.IsTrue(log.Any(line => test.Item2.All(pattern => line.Contains(pattern))), "Missing a log entry for test '" + test.Item1 + "'.");
                }

                var notExpected = new[] { "CommandsWithServerError" };

                foreach (var test in notExpected)
                {
                    Assert.IsFalse(log.Any(line => line.Contains(test)), "Unexpected log entry for test '" + test + "'.");
                }
            }
        }
Example #27
0
        public void AutomaticPropertySqlDependency()
        {
            using (var container = new RhetosTestContainer())
            {
                var dslModel = container.Resolve <IDslModel>();

                //var simpleBase = dslModel.FindByKey("DataStructureInfo TestPolymorphic.SimpleBase");
                var simple1SqlView           = dslModel.FindByKey("SqlViewInfo TestPolymorphic.Simple1_As_SimpleBase");
                var sqlViewDependsOnProperty = dslModel.FindByReference <SqlDependsOnPropertyInfo>(p => p.Dependent, simple1SqlView)
                                               .Select(dep => dep.DependsOn.GetKeyProperties()).ToList();

                TestUtility.AssertContains(
                    TestUtility.DumpSorted(sqlViewDependsOnProperty),
                    new[] { "TestPolymorphic.Simple1.Days", "TestPolymorphic.Simple1.Name" });
            }
        }
Example #28
0
        public void ParseEnclosed()
        {
            var enclosedParser = new GenericParserHelper <EnclosedConceptInfo>("enclosed");

            Stack <IConceptInfo> stack = new Stack <IConceptInfo>();

            stack.Push(new SimpleConceptInfo {
                Name = "a"
            });

            var tokenReader        = TestTokenReader("simple a { enclosed b; }", 3);
            EnclosedConceptInfo ci = (EnclosedConceptInfo)enclosedParser.Parse(tokenReader, stack).Value;

            Assert.AreEqual("a", ci.Parent.Name);
            Assert.AreEqual("b", ci.Name);
            TestUtility.AssertContains(tokenReader.ReportPosition(), "before: \";");
        }
Example #29
0
        public void FailedCleanupRollback()
        {
            var    id1       = Guid.NewGuid();
            var    log       = new List <string>();
            var    systemLog = new List <string>();
            string testName  = TestNamePrefix + Guid.NewGuid();

            using (var scope = RhetosProcessHelper.CreateScope(builder =>
                                                               builder.AddLogMonitor(systemLog, EventType.Trace)))
            {
                var transaction = scope.Resolve <IPersistenceTransaction>();
                transaction.BeforeClose += () => log.Add("before1");
                transaction.BeforeClose += () => throw new InvalidOperationException(testName + "-before");
                transaction.BeforeClose += () => log.Add("before2");
                transaction.AfterClose  += () => log.Add("after");

                var repository = scope.Resolve <Common.DomRepository>();
                repository.TestEntity.BaseEntity.Insert(new TestEntity.BaseEntity {
                    ID = id1, Name = testName
                });

                var dbTransaction = (DbTransaction)transaction.GetType().GetField("_transaction", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(transaction);
                dbTransaction.Rollback(); // This will cause error on commit or rollback, when IPersistenceTransaction is Disposed.

                systemLog.Clear();
                TestUtility.ShouldFail <InvalidOperationException>(
                    () => scope.CommitAndClose(),
                    testName + "-before");

                TestUtility.AssertContains(
                    string.Join(Environment.NewLine, systemLog),
                    new[] { "Rolling back transaction", "Closing connection" });

                TestUtility.ShouldFail <FrameworkException>(
                    () => Assert.IsNull(transaction.Connection),
                    "Trying to use the Connection property of a disposed persistence transaction.");
            }

            Assert.AreEqual("before1", TestUtility.Dump(log));
            // Failure on rollback should not throw an exception, to allow other cleanup code to be executed. Also, a previously handled database connection error may have triggered the rollback.
            using (var scope = RhetosProcessHelper.CreateScope())
            {
                var context = scope.Resolve <Common.ExecutionContext>();
                Assert.IsFalse(context.Repository.TestEntity.BaseEntity.Query(new[] { id1 }).Any());
            }
        }
        public void CommitAndReconnect()
        {
            var items = Enumerable.Range(0, 4)
                        .Select(x => new TestEntity.BaseEntity {
                ID = Guid.NewGuid(), Name = "e" + x
            })
                        .ToArray();

            var itemsIds = items.Select(item => item.ID);

            using (var container = new RhetosTestContainer(commitChanges: false))
            {
                var log = new List <string>();
                container.AddLogMonitor(log);
                var repository  = container.Resolve <Common.DomRepository>();
                var sqlExecuter = container.Resolve <ISqlExecuter>();
                var persistence = container.Resolve <IPersistenceTransaction>();

                repository.TestEntity.BaseEntity.Delete(repository.TestEntity.BaseEntity.Query());

                // Testing both EF and direct SQL commands to work well with the same transaction context:
                repository.TestEntity.BaseEntity.Insert(items[0]);
                sqlExecuter.ExecuteSql($"INSERT INTO TestEntity.BaseEntity (ID, Name) SELECT '{items[1].ID}', '{items[1].Name}'");
                Assert.AreEqual("e0, e1", TestUtility.DumpSorted(repository.TestEntity.BaseEntity.Query(itemsIds), item => item.Name));

                log.Clear();
#pragma warning disable CS0618 // Type or member is obsolete. The old feature should still work.
                persistence.CommitAndReconnect();
#pragma warning restore CS0618 // Type or member is obsolete.

                TestUtility.AssertContains(string.Join("\r\n", log), GetType().Name);

                // The following code shows the expected behavior, but it results with a database lock (EF still uses old committed transaction, while the SqlExecuter uses the new reconnected).
                // Will not fix, since the feature is not needed anymore and should be removed in the next major release.
                //repository.TestEntity.BaseEntity.Insert(items[2]);
                //sqlExecuter.ExecuteSql($"INSERT INTO TestEntity.BaseEntity (ID, Name) SELECT '{items[3].ID}', '{items[3].Name}'");
                //Assert.AreEqual("e0, e1, e2, e3", TestUtility.DumpSorted(repository.TestEntity.BaseEntity.Query(itemsIds), item => item.Name));
            }

            using (var container = new RhetosTestContainer(commitChanges: false))
            {
                var repository = container.Resolve <Common.DomRepository>();

                Assert.AreEqual("e0, e1", TestUtility.DumpSorted(repository.TestEntity.BaseEntity.Query(itemsIds), item => item.Name));
            }
        }