public void Getting_1000_Cached_Items() { // Arrange IContentType contentType = ContentTypeService.Get(ContentType.Id); IEnumerable <Content> pages = ContentBuilder.CreateTextpageContent(contentType, -1, 1000); ContentService.Save(pages, 0); using (IScope scope = ScopeProvider.CreateScope()) { DocumentRepository repository = DocumentRepository; // Act IEnumerable <IContent> contents = repository.GetMany(); var watch = Stopwatch.StartNew(); IEnumerable <IContent> contentsCached = repository.GetMany(); watch.Stop(); long elapsed = watch.ElapsedMilliseconds; Debug.Print("1000 content items retrieved in {0} ms with caching", elapsed); // Assert // Assert.That(contentsCached.Any(x => x.HasIdentity == false), Is.False); // Assert.That(contentsCached.Any(x => x == null), Is.False); // Assert.That(contentsCached.Count(), Is.EqualTo(contents.Count())); } }
public void Can_Bulk_Insert_Native_Sql_Bulk_Inserts() { var servers = new List <ServerRegistrationDto>(); for (int i = 0; i < 1000; i++) { servers.Add(new ServerRegistrationDto { ServerAddress = "address" + i, ServerIdentity = "computer" + i, DateRegistered = DateTime.Now, IsActive = true, DateAccessed = DateTime.Now }); } // Act using (ProfilingLogger.TraceDuration <NPocoBulkInsertTests>("starting insert", "finished insert")) { using (IScope scope = ScopeProvider.CreateScope()) { ScopeAccessor.AmbientScope.Database.BulkInsertRecords(servers); scope.Complete(); } } // Assert using (IScope scope = ScopeProvider.CreateScope()) { Assert.That(ScopeAccessor.AmbientScope.Database.ExecuteScalar <int>("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000)); } }
public void Can_Perform_GetAll_With_Params_On_ScriptRepository() { // Arrange using (IScope scope = ScopeProvider.CreateScope()) { IScriptRepository repository = CreateRepository(); var script = new Script("test-script1.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" }; repository.Save(script); var script2 = new Script("test-script2.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" }; repository.Save(script2); var script3 = new Script("test-script3.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" }; repository.Save(script3); // Act IEnumerable <IScript> scripts = repository.GetMany("test-script1.js", "test-script2.js"); // Assert Assert.That(scripts, Is.Not.Null); Assert.That(scripts.Any(), Is.True); Assert.That(scripts.Any(x => x == null), Is.False); Assert.That(scripts.Count(), Is.EqualTo(2)); } }
public IReadOnlyList <SavedLogSearch>?AddSavedSearch(string?name, string?query) { using IScope scope = _scopeProvider.CreateScope(autoComplete: true); _logViewerQueryRepository.Save(new LogViewerQuery(name, query)); return(GetSavedSearches()); }
public void Can_Perform_Move_On_ScriptRepository() { const string content = "/// <reference name=\"MicrosoftAjax.js\"/>"; // Arrange using (IScope scope = ScopeProvider.CreateScope()) { IScriptRepository repository = CreateRepository(); IScript script = new Script("test-move-script.js") { Content = content }; repository.Save(script); // Act script = repository.Get("test-move-script.js"); script.Path = "moved/test-move-script.js"; repository.Save(script); bool existsOld = repository.Exists("test-move-script.js"); bool existsNew = repository.Exists("moved/test-move-script.js"); script = repository.Get("moved/test-move-script.js"); // Assert Assert.IsNotNull(script); Assert.IsFalse(existsOld); Assert.IsTrue(existsNew); Assert.AreEqual(content, script.Content); } }
public void TestCalculated() { // Fetching a POCO that has a countof other POCOs, // with an n-to-n intermediate table. using (IScope scope = ScopeProvider.CreateScope()) { // This is the raw SQL, but it's better to use expressions and no magic strings! // var sql = @" // SELECT zbThing1.id, zbThing1.name, COUNT(zbThing2Group.groupId) as groupCount // FROM zbThing1 // JOIN zbThing2Group ON zbThing1.id=zbThing2Group.thingId // GROUP BY zbThing1.id, zbThing1.name"; Sql <ISqlContext> sql = ScopeAccessor.AmbientScope.SqlContext.Sql() .Select <Thing1Dto>() .Append(", COUNT(zbThing2Group.groupId) AS groupCount") // FIXME: .From <Thing1Dto>() .InnerJoin <Thing2GroupDto>().On <Thing1Dto, Thing2GroupDto>((t, t2g) => t.Id == t2g.ThingId) .GroupBy <Thing1Dto>(x => x.Id, x => x.Name); List <Thing5Dto> dtos = ScopeAccessor.AmbientScope.Database.Fetch <Thing5Dto>(sql); Assert.AreEqual(2, dtos.Count); Thing5Dto dto1 = dtos.FirstOrDefault(x => x.Id == 1); Assert.IsNotNull(dto1); Assert.AreEqual("one", dto1.Name); Assert.AreEqual(2, dto1.GroupCount); Thing5Dto dto2 = dtos.FirstOrDefault(x => x.Id == 2); Assert.IsNotNull(dto2); Assert.AreEqual("two", dto2.Name); Assert.AreEqual(1, dto2.GroupCount); } }
public void TestSql() { using (IScope scope = ScopeProvider.CreateScope()) { Sql <ISqlContext> sql = ScopeAccessor.AmbientScope.SqlContext.Sql() .SelectAll() .From <Thing1Dto>() .Where <Thing1Dto>(x => x.Id == 1); Thing1Dto dto = ScopeAccessor.AmbientScope.Database.Fetch <Thing1Dto>(sql).FirstOrDefault(); Assert.IsNotNull(dto); Assert.AreEqual("one", dto.Name); //// var sql2 = new Sql(sql.SQL, new { id = 1 }); //// WriteSql(sql2); //// dto = Database.Fetch<Thing1Dto>(sql2).FirstOrDefault(); //// Assert.IsNotNull(dto); //// Assert.AreEqual("one", dto.Name); var sql3 = new Sql(sql.SQL, 1); dto = ScopeAccessor.AmbientScope.Database.Fetch <Thing1Dto>(sql3).FirstOrDefault(); Assert.IsNotNull(dto); Assert.AreEqual("one", dto.Name); } }
public void Can_Remove_Tag_Data_To_Published_Content() { Template template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); // Arrange ContentType contentType = ContentTypeBuilder.CreateSimpleContentType("umbMandatory", "Mandatory Doc Type", mandatoryProperties: true, defaultTemplateId: template.Id); CreateAndAddTagsPropertyType(contentType); ContentTypeService.Save(contentType); Content content = ContentBuilder.CreateSimpleContent(contentType, "Tagged content", -1); content.AssignTags(PropertyEditorCollection, DataTypeService, Serializer, "tags", new[] { "hello", "world", "some", "tags" }); ContentService.SaveAndPublish(content); // Act content.RemoveTags(PropertyEditorCollection, DataTypeService, Serializer, "tags", new[] { "some", "world" }); ContentService.SaveAndPublish(content); // Assert Assert.AreEqual(2, content.Properties["tags"].GetValue().ToString().Split(',').Distinct().Count()); int propertyTypeId = contentType.PropertyTypes.Single(x => x.Alias == "tags").Id; using (IScope scope = ScopeProvider.CreateScope()) { Assert.AreEqual(2, ScopeAccessor.AmbientScope.Database.ExecuteScalar <int>( "SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId", new { nodeId = content.Id, propTypeId = propertyTypeId })); scope.Complete(); } }
public void TestOneToManyOnManyTemplate() { using (IScope scope = ScopeProvider.CreateScope()) { ScopeAccessor.AmbientScope.SqlContext.Templates.Clear(); Sql <ISqlContext> sql = ScopeAccessor.AmbientScope.SqlContext.Templates.Get("xxx", s => s .Select <Thing3Dto>(r => r.Select(x => x.Things)) // select Thing3Dto, and Thing2Dto for Things .From <Thing3Dto>() .InnerJoin <Thing2Dto>().On <Thing3Dto, Thing2Dto>(left => left.Id, right => right.ThingId) .OrderBy <Thing3Dto>(x => x.Id)).Sql(); // cached sql = ScopeAccessor.AmbientScope.SqlContext.Templates.Get("xxx", s => throw new InvalidOperationException()).Sql(); List <Thing3Dto> dtos = ScopeAccessor.AmbientScope.Database.FetchOneToMany <Thing3Dto>(x => x.Things, /*x => x.Id,*/ sql); Assert.AreEqual(2, dtos.Count); Thing3Dto dto1 = dtos.FirstOrDefault(x => x.Id == 1); Assert.IsNotNull(dto1); Assert.AreEqual("one", dto1.Name); Assert.IsNotNull(dto1.Things); Assert.AreEqual(2, dto1.Things.Count); Thing2Dto dto2 = dto1.Things.FirstOrDefault(x => x.Id == 1); Assert.IsNotNull(dto2); Assert.AreEqual("uno", dto2.Name); } }
public void TestOneToManyOnOne() { // Fetching a POCO that has a list of other POCOs, // and fetching these POCOs at the same time, // with a pk/fk relationship // for one single POCO. using (IScope scope = ScopeProvider.CreateScope()) { // This is the raw SQL, but it's better to use expressions and no magic strings! // var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, x => x.Id, @" // SELECT zbThing1.id AS Id, zbThing1.name AS Name, // zbThing2.id AS Things__Id, zbThing2.name AS Things__Name, zbThing2.thingId AS Things__ThingId // FROM zbThing1 // JOIN zbThing2 ON zbThing1.id=zbThing2.thingId // WHERE zbThing1.id=1"); Sql <ISqlContext> sql = ScopeAccessor.AmbientScope.SqlContext.Sql() .Select <Thing3Dto>(r => r.Select(x => x.Things)) .From <Thing3Dto>() .InnerJoin <Thing2Dto>().On <Thing3Dto, Thing2Dto>(left => left.Id, right => right.ThingId) .Where <Thing3Dto>(x => x.Id == 1); // var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, x => x.Id, sql); List <Thing3Dto> dtos = ScopeAccessor.AmbientScope.Database.FetchOneToMany <Thing3Dto>(x => x.Things, sql); Assert.AreEqual(1, dtos.Count); Thing3Dto dto1 = dtos.FirstOrDefault(x => x.Id == 1); Assert.IsNotNull(dto1); Assert.AreEqual("one", dto1.Name); Assert.IsNotNull(dto1.Things); Assert.AreEqual(2, dto1.Things.Count); Thing2Dto dto2 = dto1.Things.FirstOrDefault(x => x.Id == 1); Assert.IsNotNull(dto2); Assert.AreEqual("uno", dto2.Name); } }
public void Create_Tag_Data_Bulk_Publish_Operation() { // Arrange // set configuration IDataType dataType = DataTypeService.GetDataType(1041); dataType.Configuration = new TagConfiguration { Group = "test", StorageType = TagsStorageType.Csv }; Template template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); ContentType contentType = ContentTypeBuilder.CreateSimpleContentType("umbMandatory", "Mandatory Doc Type", mandatoryProperties: true, defaultTemplateId: template.Id); CreateAndAddTagsPropertyType(contentType); ContentTypeService.Save(contentType); contentType.AllowedContentTypes = new[] { new ContentTypeSort(new Lazy <int>(() => contentType.Id), 0, contentType.Alias) }; Content content = ContentBuilder.CreateSimpleContent(contentType, "Tagged content", -1); content.AssignTags(PropertyEditorCollection, DataTypeService, Serializer, "tags", new[] { "hello", "world", "some", "tags" }); ContentService.Save(content); Content child1 = ContentBuilder.CreateSimpleContent(contentType, "child 1 content", content.Id); child1.AssignTags(PropertyEditorCollection, DataTypeService, Serializer, "tags", new[] { "hello1", "world1", "some1" }); ContentService.Save(child1); Content child2 = ContentBuilder.CreateSimpleContent(contentType, "child 2 content", content.Id); child2.AssignTags(PropertyEditorCollection, DataTypeService, Serializer, "tags", new[] { "hello2", "world2" }); ContentService.Save(child2); // Act ContentService.SaveAndPublishBranch(content, true); // Assert int propertyTypeId = contentType.PropertyTypes.Single(x => x.Alias == "tags").Id; using (IScope scope = ScopeProvider.CreateScope()) { Assert.AreEqual(4, ScopeAccessor.AmbientScope.Database.ExecuteScalar <int>( "SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId", new { nodeId = content.Id, propTypeId = propertyTypeId })); Assert.AreEqual(3, ScopeAccessor.AmbientScope.Database.ExecuteScalar <int>( "SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId", new { nodeId = child1.Id, propTypeId = propertyTypeId })); Assert.AreEqual(2, ScopeAccessor.AmbientScope.Database.ExecuteScalar <int>( "SELECT COUNT(*) FROM cmsTagRelationship WHERE nodeId=@nodeId AND propertyTypeId=@propTypeId", new { nodeId = child2.Id, propTypeId = propertyTypeId })); scope.Complete(); } }
public void Generate_Bulk_Import_Sql() { var servers = new List <ServerRegistrationDto>(); for (int i = 0; i < 2; i++) { servers.Add(new ServerRegistrationDto { ServerAddress = "address" + i, ServerIdentity = "computer" + i, DateRegistered = DateTime.Now, IsActive = true, DateAccessed = DateTime.Now }); } IDbCommand[] commands; using (IScope scope = ScopeProvider.CreateScope()) { commands = ScopeAccessor.AmbientScope.Database.GenerateBulkInsertCommands(servers.ToArray()); scope.Complete(); } // Assert Assert.That( commands[0].CommandText, Is.EqualTo("INSERT INTO [umbracoServer] ([umbracoServer].[address], [umbracoServer].[computerName], [umbracoServer].[registeredDate], [umbracoServer].[lastNotifiedDate], [umbracoServer].[isActive], [umbracoServer].[isSchedulingPublisher]) VALUES (@0,@1,@2,@3,@4,@5), (@6,@7,@8,@9,@10,@11)")); }
public void Generate_Bulk_Import_Sql_Exceeding_Max_Params() { var servers = new List <ServerRegistrationDto>(); for (int i = 0; i < 1500; i++) { servers.Add(new ServerRegistrationDto { ServerAddress = "address" + i, ServerIdentity = "computer" + i, DateRegistered = DateTime.Now, IsActive = true, DateAccessed = DateTime.Now, IsSchedulingPublisher = true }); } IDbCommand[] commands; using (IScope scope = ScopeProvider.CreateScope()) { commands = ScopeAccessor.AmbientScope.Database.GenerateBulkInsertCommands(servers.ToArray()); scope.Complete(); } // Assert Assert.That(commands.Length, Is.EqualTo(5)); foreach (string s in commands.Select(x => x.CommandText)) { Assert.LessOrEqual(Regex.Matches(s, "@\\d+").Count, 2000); } }
public void Can_Perform_Update_On_ScriptRepository() { // Arrange IScopeProvider provider = ScopeProvider; using (IScope scope = ScopeProvider.CreateScope()) { IScriptRepository repository = CreateRepository(); // Act var script = new Script("test-updated-script.js") { Content = "/// <reference name=\"MicrosoftAjax.js\"/>" }; repository.Save(script); script.Content = "/// <reference name=\"MicrosoftAjax-Updated.js\"/>"; repository.Save(script); IScript scriptUpdated = repository.Get("test-updated-script.js"); // Assert Assert.That(_fileSystem.FileExists("test-updated-script.js"), Is.True); Assert.That(scriptUpdated.Content, Is.EqualTo("/// <reference name=\"MicrosoftAjax-Updated.js\"/>")); } }
public void DeleteKeysAndIndexesOfTDto() { IMigrationBuilder builder = Mock.Of <IMigrationBuilder>(); Mock.Get(builder) .Setup(x => x.Build(It.IsAny <Type>(), It.IsAny <IMigrationContext>())) .Returns <Type, IMigrationContext>((t, c) => { switch (t.Name) { case "CreateTableOfTDtoMigration": return(new CreateTableOfTDtoMigration(c)); case "DeleteKeysAndIndexesMigration": return(new DeleteKeysAndIndexesMigration(c)); default: throw new NotSupportedException(); } }); using (IScope scope = ScopeProvider.CreateScope()) { var upgrader = new Upgrader( new MigrationPlan("test") .From(string.Empty) .To <CreateTableOfTDtoMigration>("a") .To <DeleteKeysAndIndexesMigration>("done")); upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of <IKeyValueService>()); scope.Complete(); } }
protected void SeedDatabase() { using (IScope scope = ScopeProvider.CreateScope()) { InsertData(ScopeAccessor.AmbientScope.Database); scope.Complete(); } }
public void WriteLockExisting() { IScopeProvider provider = ScopeProvider; using (IScope scope = provider.CreateScope()) { scope.EagerWriteLock(Constants.Locks.Servers); scope.Complete(); } }
public void GivenSuppressedNotificationsOnParent_WhenChildSuppresses_ThenExceptionIsThrown() { using (IScope parentScope = ScopeProvider.CreateScope(autoComplete: true)) using (IDisposable parentSuppressed = parentScope.Notifications.Suppress()) { using (IScope childScope = ScopeProvider.CreateScope(autoComplete: true)) { Assert.Throws <InvalidOperationException>(() => childScope.Notifications.Suppress()); } } }
public IReadOnlyList <SavedLogSearch>?GetSavedSearches() { using IScope scope = _scopeProvider.CreateScope(autoComplete: true); IEnumerable <ILogViewerQuery>?logViewerQueries = _logViewerQueryRepository.GetMany(); SavedLogSearch[]? result = logViewerQueries?.Select(x => new SavedLogSearch() { Name = x.Name, Query = x.Query }).ToArray(); return(result); }
public void Can_Perform_Count_On_DataTypeDefinitionRepository() { using (IScope scope = ScopeProvider.CreateScope()) { // Act IQuery <IDataType> query = ScopeProvider.CreateQuery <IDataType>().Where(x => x.Name.StartsWith("D")); int count = DataTypeRepository.Count(query); // Assert Assert.That(count, Is.EqualTo(4)); } }
public void GivenScope_WhenNotificationsSuppressed_ThenNotificationsDoNotExecute() { using IScope scope = ScopeProvider.CreateScope(autoComplete: true); using IDisposable _ = scope.Notifications.Suppress(); ContentType contentType = ContentTypeBuilder.CreateBasicContentType(); ContentTypeService.Save(contentType); Content content = ContentBuilder.CreateBasicContent(contentType); ContentService.Save(content); }
public IReadOnlyList <SavedLogSearch>?DeleteSavedSearch(string?name, string?query) { using IScope scope = _scopeProvider.CreateScope(autoComplete: true); ILogViewerQuery?item = name is null ? null : _logViewerQueryRepository.GetByName(name); if (item is not null) { _logViewerQueryRepository.Delete(item); } // Return the updated object - so we can instantly reset the entire array from the API response return(GetSavedSearches()); }
public void WriteLockNonExisting() { IScopeProvider provider = ScopeProvider; Assert.Throws <ArgumentException>(() => { using (IScope scope = provider.CreateScope()) { scope.EagerWriteLock(-666); scope.Complete(); } }); }
private void Save(MediaService service, IMedia media) { using (IScope scope = ScopeProvider.CreateScope()) { if (ScopeAccessor.AmbientScope.Database.DatabaseType.IsSqlServer()) { ScopeAccessor.AmbientScope.Database.Execute("SET LOCK_TIMEOUT 60000"); } service.Save(media); scope.Complete(); } }
public void Can_Bulk_Insert_Native_Sql_Server_Bulk_Inserts() { // create the db // prob not what we want, this is not a real database, but hey, the test is ignored anyways // we'll fix this when we have proper testing infrastructure // var dbSqlServer = TestObjects.GetUmbracoSqlServerDatabase(new NullLogger<UmbracoDatabase>()); using (IScope scope = ScopeProvider.CreateScope()) { // Still no what we want, but look above. IUmbracoDatabase dbSqlServer = ScopeAccessor.AmbientScope.Database; // drop the table dbSqlServer.Execute("DROP TABLE [umbracoServer]"); // re-create it dbSqlServer.Execute(@"CREATE TABLE [umbracoServer]( [id] [int] IDENTITY(1,1) NOT NULL, [address] [nvarchar](500) NOT NULL, [computerName] [nvarchar](255) NOT NULL, [registeredDate] [datetime] NOT NULL CONSTRAINT [DF_umbracoServer_registeredDate] DEFAULT (getdate()), [lastNotifiedDate] [datetime] NOT NULL, [isActive] [bit] NOT NULL, [isMaster] [bit] NOT NULL, CONSTRAINT [PK_umbracoServer] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] )"); var data = new List <ServerRegistrationDto>(); for (int i = 0; i < 1000; i++) { data.Add(new ServerRegistrationDto { ServerAddress = "address" + i, ServerIdentity = "computer" + i, DateRegistered = DateTime.Now, IsActive = true, DateAccessed = DateTime.Now }); } using (ITransaction tr = dbSqlServer.GetTransaction()) { dbSqlServer.BulkInsertRecords(data); tr.Complete(); } // Assert Assert.That(dbSqlServer.ExecuteScalar <int>("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000)); } }
public void Can_Perform_GetByQuery_On_DataTypeDefinitionRepository() { using (IScope scope = ScopeProvider.CreateScope()) { // Act IQuery <IDataType> query = ScopeProvider.CreateQuery <IDataType>().Where(x => x.EditorAlias == Constants.PropertyEditors.Aliases.RadioButtonList); IDataType[] result = DataTypeRepository.Get(query).ToArray(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Any(), Is.True); Assert.That(result.FirstOrDefault()?.Name, Is.EqualTo("Radiobox")); } }
public void Can_Instantiate_Repository() { // Arrange IScopeProvider provider = ScopeProvider; using (IScope scope = ScopeProvider.CreateScope()) { // Act IScriptRepository repository = CreateRepository(); // Assert Assert.That(repository, Is.Not.Null); } }
public void Can_Perform_Exists_On_ScriptRepository() { // Arrange using (IScope scope = ScopeProvider.CreateScope()) { IScriptRepository repository = CreateRepository(); // Act bool exists = repository.Exists("test-script.js"); // Assert Assert.That(exists, Is.True); } }
public void Can_Perform_Delete_On_ScriptRepository() { // Arrange using (IScope scope = ScopeProvider.CreateScope()) { IScriptRepository repository = CreateRepository(); // Act IScript script = repository.Get("test-script.js"); repository.Delete(script); // Assert Assert.IsFalse(repository.Exists("test-script.js")); } }
public void Removes_Existing_Duplicates_On_Save() { var user = new UserBuilder().Build(); UserService.Save(user); string providerKey = Guid.NewGuid().ToString("N"); DateTime latest = DateTime.Now.AddDays(-1); DateTime oldest = DateTime.Now.AddDays(-10); using (IScope scope = ScopeProvider.CreateScope()) { // insert duplicates manuall ScopeAccessor.AmbientScope.Database.Insert(new ExternalLoginDto { UserOrMemberKey = user.Key, LoginProvider = "test1", ProviderKey = providerKey, CreateDate = latest }); ScopeAccessor.AmbientScope.Database.Insert(new ExternalLoginDto { UserOrMemberKey = user.Key, LoginProvider = "test1", ProviderKey = providerKey, CreateDate = oldest }); } // try to save 2 other duplicates ExternalLogin[] externalLogins = new[] { new ExternalLogin("test2", providerKey), new ExternalLogin("test2", providerKey), new ExternalLogin("test1", providerKey) }; ExternalLoginService.Save(user.Key, externalLogins); var logins = ExternalLoginService.GetExternalLogins(user.Key).ToList(); // duplicates will be removed, keeping the latest entries Assert.AreEqual(2, logins.Count); IIdentityUserLogin test1 = logins.Single(x => x.LoginProvider == "test1"); Assert.Greater(test1.CreateDate, latest); }