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; } }
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."); }
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)); }
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)); }
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"); } }
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"); } }
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" }); }
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); } }
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); } } }
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"); } }
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."); }
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."); }
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); }
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" }); }
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,"); }
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."); } }
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 }
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" }); } }
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."); } }
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" }); } }
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" }); } }
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 + "'."); } } }
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" }); } }
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: \";"); }
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)); } }