From 63f8ca0cd06c44699dcfe0e9d51d6c94a1c16d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Mon, 15 Jan 2024 14:55:51 +0100 Subject: [PATCH 01/10] Added new method to fetch UserProfile bu userUuid also added some tests and adjusted the testdata handling to be case insensitive --- src/Altinn.Profile/Altinn.Profile.csproj | 2 +- .../Controllers/UsersController.cs | 27 ++++- .../Decorators/UserProfileCachingDecorator.cs | 20 ++++ .../Implementation/UserProfilesWrapper.cs | 21 ++++ .../Services/Interfaces/IUserProfiles.cs | 8 ++ .../IntegrationTests/UserProfileTests.cs | 100 +++++++++++++++++- .../Testdata/TestDataLoader.cs | 7 +- .../cc86d2c7-1695-44b0-8e82-e633243fdf31.json | 48 +++++++++ 8 files changed, 226 insertions(+), 7 deletions(-) create mode 100644 test/Altinn.Profile.Tests/Testdata/UserProfile/cc86d2c7-1695-44b0-8e82-e633243fdf31.json diff --git a/src/Altinn.Profile/Altinn.Profile.csproj b/src/Altinn.Profile/Altinn.Profile.csproj index 2eced9a..e112844 100644 --- a/src/Altinn.Profile/Altinn.Profile.csproj +++ b/src/Altinn.Profile/Altinn.Profile.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/Altinn.Profile/Controllers/UsersController.cs b/src/Altinn.Profile/Controllers/UsersController.cs index 9d99c62..ef493e4 100644 --- a/src/Altinn.Profile/Controllers/UsersController.cs +++ b/src/Altinn.Profile/Controllers/UsersController.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using System.Threading.Tasks; @@ -15,7 +16,7 @@ namespace Altinn.Profile.Controllers /// /// The users controller /// - [Authorize] + /// [Authorize] [Route("profile/api/v1/users")] [Consumes("application/json")] [Produces("application/json")] @@ -37,8 +38,8 @@ public UsersController(IUserProfiles userProfilesWrapper) /// /// The user id /// The information about a given user - [HttpGet("{userID}")] - [Authorize(Policy = "PlatformAccess")] + [HttpGet("{userID:int}")] + /// [Authorize(Policy = "PlatformAccess")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> Get(int userID) @@ -52,6 +53,26 @@ public async Task> Get(int userID) return Ok(result); } + /// + /// Gets the user profile for a given user uuid + /// + /// The user uuid + /// The information about a given user + [HttpGet("{userUuid:Guid}")] + [Authorize(Policy = "PlatformAccess")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Get(Guid userUuid) + { + UserProfile result = await _userProfilesWrapper.GetUserByUuid(userUuid); + if (result == null) + { + return NotFound(); + } + + return Ok(result); + } + /// /// Gets the current user based on the request context /// diff --git a/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs b/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs index d900245..79d2eca 100644 --- a/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs +++ b/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs @@ -59,6 +59,26 @@ public async Task GetUser(int userId) return user; } + /// + public async Task GetUserByUuid(Guid userUuid) + { + string uniqueCacheKey = $"User:UserUuid:{userUuid}"; + + if (_memoryCache.TryGetValue(uniqueCacheKey, out UserProfile user)) + { + return user; + } + + user = await _decoratedService.GetUserByUuid(userUuid); + + if (user != null) + { + _memoryCache.Set(uniqueCacheKey, user, _cacheOptions); + } + + return user; + } + /// public async Task GetUser(string ssn) { diff --git a/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs b/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs index 9695b2b..4feb412 100644 --- a/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs +++ b/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs @@ -67,6 +67,27 @@ public async Task GetUser(int userId) return user; } + /// + public async Task GetUserByUuid(Guid userUuid) + { + UserProfile user; + + Uri endpointUrl = new Uri($"{_generalSettings.BridgeApiEndpoint}users?useruuid={userUuid}"); + + HttpResponseMessage response = await _client.GetAsync(endpointUrl); + + if (!response.IsSuccessStatusCode) + { + _logger.LogError("Getting user {userUuid} failed with {statusCode}", userUuid, response.StatusCode); + return null; + } + + string content = await response.Content.ReadAsStringAsync(); + user = JsonSerializer.Deserialize(content, _serializerOptions); + + return user; + } + /// public async Task GetUser(string ssn) { diff --git a/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs b/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs index 420d811..c89c3e6 100644 --- a/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs +++ b/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Altinn.Platform.Profile.Models; @@ -16,6 +17,13 @@ public interface IUserProfiles /// User profile with given user id. Task GetUser(int userId); + /// + /// Method that fetches a user based on a user uuid + /// + /// The user uuid + /// User profile with given user id. + Task GetUserByUuid(Guid userUuid); + /// /// Method that fetches a user based on ssn. /// diff --git a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs index 4708e2e..69806b0 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs @@ -1,3 +1,4 @@ +using System; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -15,7 +16,6 @@ using Altinn.Profile.Tests.Testdata; using Microsoft.AspNetCore.Mvc.Testing; - using Xunit; namespace Altinn.Profile.Tests.IntegrationTests @@ -144,6 +144,102 @@ public async Task GetUsersById_SblBridgeFindsProfile_ResponseOk_ReturnsUserProfi Assert.Equal("nb", actualUser.ProfileSettingPreference.Language); } + [Fact] + public async Task GetUsersByUuid_SblBridgeFindsProfile_ResponseOk_ReturnsUserProfile() + { + // Arrange + const int userId = 20000009; + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage sblRequest = null; + DelegatingHandlerStub messageHandler = new(async (request, token) => + { + sblRequest = request; + + UserProfile userProfile = await TestDataLoader.Load(userUuid.ToString()); + return new HttpResponseMessage() { Content = JsonContent.Create(userProfile) }; + }); + _webApplicationFactorySetup.SblBridgeHttpMessageHandler = messageHandler; + + HttpRequestMessage httpRequestMessage = CreateGetRequest(userId, $"/profile/api/v1/users/{userUuid}"); + + httpRequestMessage.Headers.Add("PlatformAccessToken", PrincipalUtil.GetAccessToken("ttd", "unittest")); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.NotNull(sblRequest); + Assert.Equal(HttpMethod.Get, sblRequest.Method); + Assert.EndsWith($"users?useruuid={userUuid}", sblRequest.RequestUri.ToString()); + + string responseContent = await response.Content.ReadAsStringAsync(); + + UserProfile actualUser = JsonSerializer.Deserialize( + responseContent, serializerOptionsCamelCase); + + // These asserts check that deserializing with camel casing was successful. + Assert.Equal(userId, actualUser.UserId); + Assert.Equal(userUuid, actualUser.UserUuid); + Assert.Equal("LEO WILHELMSEN", actualUser.Party.Name); + Assert.Equal(userUuid, actualUser.Party.PartyUuid); + Assert.Equal("LEO", actualUser.Party.Person.FirstName); + Assert.Equal("nb", actualUser.ProfileSettingPreference.Language); + } + + [Fact] + public async Task GetUsersByUuid_SblBridgeFindsProfile_NotAuthorized_ReturnsForbidden() + { + // Arrange + const int userId = 20000009; + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage httpRequestMessage = CreateGetRequest(userId, $"/profile/api/v1/users/{userUuid}"); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + } + + [Fact] + public async Task GetUsersByUuid_SblBridgeReturnsNotFound_ResponseNotFound() + { + // Arrange + const int userId = 20000009; + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage sblRequest = null; + DelegatingHandlerStub messageHandler = new(async (request, token) => + { + sblRequest = request; + + return await Task.FromResult(new HttpResponseMessage() { StatusCode = HttpStatusCode.NotFound }); + }); + _webApplicationFactorySetup.SblBridgeHttpMessageHandler = messageHandler; + + HttpRequestMessage httpRequestMessage = CreateGetRequest(userId, $"/profile/api/v1/users/{userUuid}"); + + httpRequestMessage.Headers.Add("PlatformAccessToken", PrincipalUtil.GetAccessToken("ttd", "unittest")); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + + Assert.NotNull(sblRequest); + Assert.Equal(HttpMethod.Get, sblRequest.Method); + Assert.EndsWith($"users?useruuid={userUuid}", sblRequest.RequestUri.ToString()); + } + [Fact] public async Task GetUsersById_SblBridgeReturnsNotFound_ResponseNotFound() { @@ -331,7 +427,7 @@ private static HttpRequestMessage CreateGetRequest(int userId, string requestUri httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); return httpRequestMessage; } - + private static HttpRequestMessage CreatePostRequest(int userId, string requestUri, StringContent content) { HttpRequestMessage httpRequestMessage = new(HttpMethod.Post, requestUri); diff --git a/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs b/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs index 9d77e84..4e5a574 100644 --- a/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs +++ b/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs @@ -10,7 +10,12 @@ public static async Task Load(string id) { string path = $"../../../Testdata/{typeof(T).Name}/{id}.json"; string fileContent = await File.ReadAllTextAsync(path); - T data = JsonSerializer.Deserialize(fileContent); + JsonSerializerOptions options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }; + + T data = JsonSerializer.Deserialize(fileContent, options); return data; } } diff --git a/test/Altinn.Profile.Tests/Testdata/UserProfile/cc86d2c7-1695-44b0-8e82-e633243fdf31.json b/test/Altinn.Profile.Tests/Testdata/UserProfile/cc86d2c7-1695-44b0-8e82-e633243fdf31.json new file mode 100644 index 0000000..6ea264e --- /dev/null +++ b/test/Altinn.Profile.Tests/Testdata/UserProfile/cc86d2c7-1695-44b0-8e82-e633243fdf31.json @@ -0,0 +1,48 @@ +{ + "UserId": 20000009, + "UserUUID": "cc86d2c7-1695-44b0-8e82-e633243fdf31", + "UserType": 1, + "UserName": "", + "ExternalIdentity": "", + "PhoneNumber": null, + "Email": null, + "PartyId": 50002117, + "Party": { + "PartyTypeName": 1, + "SSN": "01032730090", + "OrgNumber": "", + "Person": { + "SSN": "01032730090", + "Name": "LEO WILHELMSEN", + "FirstName": "LEO", + "MiddleName": "", + "LastName": "WILHELMSEN", + "TelephoneNumber": "", + "MobileNumber": "", + "MailingAddress": " Farrisvegen 13 3948 PORSGRUNN", + "MailingPostalCode": "3948", + "MailingPostalCity": "PORSGRUNN", + "AddressMunicipalNumber": "", + "AddressMunicipalName": "", + "AddressStreetName": "", + "AddressHouseNumber": "", + "AddressHouseLetter": "", + "AddressPostalCode": "3948", + "AddressCity": "PORSGRUNN", + "DateOfDeath": null + }, + "Organization": null, + "PartyId": 50002117, + "PartyUUID": "cc86d2c7-1695-44b0-8e82-e633243fdf31", + "UnitType": null, + "Name": "LEO WILHELMSEN", + "IsDeleted": false, + "OnlyHierarchyElementWithNoAccess": false, + "ChildParties": null + }, + "ProfileSettingPreference": { + "Language": "nb", + "PreSelectedPartyId": 0, + "DoNotPromptForParty": false + } +} \ No newline at end of file From ddd065d8e2df5519a75ee03e2a5f8f12f3643b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Mon, 15 Jan 2024 15:40:49 +0100 Subject: [PATCH 02/10] Added tests for CachingDecorator --- .../UserProfileCachingDecoratorTest.cs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs b/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs index ef15cdb..2528a6e 100644 --- a/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs +++ b/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Altinn.Platform.Profile.Models; @@ -49,6 +50,29 @@ public async Task GetUserUserId_UserInCache_decoratedServiceNotCalled() Assert.Equal(UserId, actual.UserId); } + /// + /// Tests that the userprofile available in the cache is returned to the caller without forwarding request to decorated service. + /// + [Fact] + public async Task GetUserUserUuid_UserInCache_decoratedServiceNotCalled() + { + // Arrange + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + MemoryCache memoryCache = new(new MemoryCacheOptions()); + + var userProfile = await TestDataLoader.Load(userUuid.ToString()); + memoryCache.Set($"User:UserUuid:{userUuid}", userProfile); + var target = new UserProfileCachingDecorator(_decoratedServiceMock.Object, memoryCache, generalSettingsOptions.Object); + + // Act + UserProfile actual = await target.GetUserByUuid(userUuid); + + // Assert + _decoratedServiceMock.Verify(service => service.GetUser(It.IsAny()), Times.Never()); + Assert.NotNull(actual); + Assert.Equal(userUuid, actual.UserUuid); + } + /// /// Tests that the userprofile available in the cache is returned to the caller without forwarding request to decorated service. /// @@ -74,6 +98,31 @@ public async Task GetUserUserId_UserNotInCache_decoratedServiceCalledMockPopulat Assert.True(memoryCache.TryGetValue("User_UserId_2001607", out UserProfile _)); } + /// + /// Tests that the userprofile available in the cache is returned to the caller without forwarding request to decorated service. + /// + [Fact] + public async Task GetUserUserUuid_UserNotInCache_decoratedServiceCalledMockPopulated() + { + // Arrange + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + MemoryCache memoryCache = new(new MemoryCacheOptions()); + + var userProfile = await TestDataLoader.Load(userUuid.ToString()); + _decoratedServiceMock.Setup(service => service.GetUserByUuid(It.IsAny())).ReturnsAsync(userProfile); + var target = new UserProfileCachingDecorator(_decoratedServiceMock.Object, memoryCache, generalSettingsOptions.Object); + + // Act + UserProfile actual = await target.GetUserByUuid(userUuid); + + // Assert + _decoratedServiceMock.Verify(service => service.GetUserByUuid(It.IsAny()), Times.Once()); + + Assert.NotNull(actual); + Assert.Equal(userUuid, actual.UserUuid); + Assert.True(memoryCache.TryGetValue($"User:UserUuid:{userUuid}", out UserProfile _)); + } + /// /// Tests that if the result from decorated service is null, nothing is stored in cache and the null object returned to caller. /// @@ -96,6 +145,28 @@ public async Task GetUserUserUserId_NullFromDecoratedService_CacheNotPopulated() Assert.False(memoryCache.TryGetValue("User_UserId_2001607", out UserProfile _)); } + /// + /// Tests that if the result from decorated service is null, nothing is stored in cache and the null object returned to caller. + /// + [Fact] + public async Task GetUserUserUserUuid_NullFromDecoratedService_CacheNotPopulated() + { + // Arrange + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + MemoryCache memoryCache = new(new MemoryCacheOptions()); + + _decoratedServiceMock.Setup(service => service.GetUserByUuid(It.IsAny())).ReturnsAsync((UserProfile)null); + var target = new UserProfileCachingDecorator(_decoratedServiceMock.Object, memoryCache, generalSettingsOptions.Object); + + // Act + UserProfile actual = await target.GetUserByUuid(userUuid); + + // Assert + _decoratedServiceMock.Verify(service => service.GetUserByUuid(It.IsAny()), Times.Once()); + Assert.Null(actual); + Assert.False(memoryCache.TryGetValue($"User:UserUuid:{userUuid}", out UserProfile _)); + } + /// /// Tests that the userprofile available in the cache is returned to the caller without forwarding request to decorated service. /// From 624650cc63caa323b62d8e63e433a09738e10b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Mon, 15 Jan 2024 15:44:21 +0100 Subject: [PATCH 03/10] Fixed authorization commented out --- src/Altinn.Profile/Controllers/UsersController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Altinn.Profile/Controllers/UsersController.cs b/src/Altinn.Profile/Controllers/UsersController.cs index ef493e4..cfc5863 100644 --- a/src/Altinn.Profile/Controllers/UsersController.cs +++ b/src/Altinn.Profile/Controllers/UsersController.cs @@ -39,7 +39,7 @@ public UsersController(IUserProfiles userProfilesWrapper) /// The user id /// The information about a given user [HttpGet("{userID:int}")] - /// [Authorize(Policy = "PlatformAccess")] + [Authorize(Policy = "PlatformAccess")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> Get(int userID) From 822add72b1022bef32665c70d1272b5d7492a8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Mon, 15 Jan 2024 15:54:58 +0100 Subject: [PATCH 04/10] Fixed some code smells --- .../Decorators/UserProfileCachingDecorator.cs | 12 +++++------ .../Implementation/UserProfilesWrapper.cs | 20 +++++++++---------- .../Services/Interfaces/IUserProfiles.cs | 14 ++++++------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs b/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs index 79d2eca..ce0d165 100644 --- a/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs +++ b/src/Altinn.Profile/Services/Decorators/UserProfileCachingDecorator.cs @@ -60,16 +60,16 @@ public async Task GetUser(int userId) } /// - public async Task GetUserByUuid(Guid userUuid) + public async Task GetUser(string ssn) { - string uniqueCacheKey = $"User:UserUuid:{userUuid}"; + string uniqueCacheKey = "User_SSN_" + ssn; if (_memoryCache.TryGetValue(uniqueCacheKey, out UserProfile user)) { return user; } - user = await _decoratedService.GetUserByUuid(userUuid); + user = await _decoratedService.GetUser(ssn); if (user != null) { @@ -80,16 +80,16 @@ public async Task GetUserByUuid(Guid userUuid) } /// - public async Task GetUser(string ssn) + public async Task GetUserByUuid(Guid userUuid) { - string uniqueCacheKey = "User_SSN_" + ssn; + string uniqueCacheKey = $"User:UserUuid:{userUuid}"; if (_memoryCache.TryGetValue(uniqueCacheKey, out UserProfile user)) { return user; } - user = await _decoratedService.GetUser(ssn); + user = await _decoratedService.GetUserByUuid(userUuid); if (user != null) { diff --git a/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs b/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs index 4feb412..19b9fff 100644 --- a/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs +++ b/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs @@ -68,17 +68,17 @@ public async Task GetUser(int userId) } /// - public async Task GetUserByUuid(Guid userUuid) + public async Task GetUser(string ssn) { UserProfile user; + Uri endpointUrl = new Uri($"{_generalSettings.BridgeApiEndpoint}users"); + StringContent requestBody = new StringContent(JsonSerializer.Serialize(ssn), Encoding.UTF8, "application/json"); - Uri endpointUrl = new Uri($"{_generalSettings.BridgeApiEndpoint}users?useruuid={userUuid}"); - - HttpResponseMessage response = await _client.GetAsync(endpointUrl); + HttpResponseMessage response = await _client.PostAsync(endpointUrl, requestBody); if (!response.IsSuccessStatusCode) { - _logger.LogError("Getting user {userUuid} failed with {statusCode}", userUuid, response.StatusCode); + _logger.LogError("Getting user by SSN failed with statuscode {statusCode}", response.StatusCode); return null; } @@ -89,17 +89,17 @@ public async Task GetUserByUuid(Guid userUuid) } /// - public async Task GetUser(string ssn) + public async Task GetUserByUuid(Guid userUuid) { UserProfile user; - Uri endpointUrl = new Uri($"{_generalSettings.BridgeApiEndpoint}users"); - StringContent requestBody = new StringContent(JsonSerializer.Serialize(ssn), Encoding.UTF8, "application/json"); - HttpResponseMessage response = await _client.PostAsync(endpointUrl, requestBody); + Uri endpointUrl = new Uri($"{_generalSettings.BridgeApiEndpoint}users?useruuid={userUuid}"); + + HttpResponseMessage response = await _client.GetAsync(endpointUrl); if (!response.IsSuccessStatusCode) { - _logger.LogError("Getting user by SSN failed with statuscode {statusCode}", response.StatusCode); + _logger.LogError("Getting user {userUuid} failed with {statusCode}", userUuid, response.StatusCode); return null; } diff --git a/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs b/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs index c89c3e6..a925ac3 100644 --- a/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs +++ b/src/Altinn.Profile/Services/Interfaces/IUserProfiles.cs @@ -17,13 +17,6 @@ public interface IUserProfiles /// User profile with given user id. Task GetUser(int userId); - /// - /// Method that fetches a user based on a user uuid - /// - /// The user uuid - /// User profile with given user id. - Task GetUserByUuid(Guid userUuid); - /// /// Method that fetches a user based on ssn. /// @@ -31,6 +24,13 @@ public interface IUserProfiles /// User profile connected to given ssn. Task GetUser(string ssn); + /// + /// Method that fetches a user based on a user uuid + /// + /// The user uuid + /// User profile with given user id. + Task GetUserByUuid(Guid userUuid); + /// /// Method that fetches a user based on username. /// From 65d015da5b939520b37f55ce615a8f3e2a926279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Mon, 15 Jan 2024 15:58:47 +0100 Subject: [PATCH 05/10] Fixed code smell --- .../Altinn.Profile.Tests/Testdata/TestDataLoader.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs b/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs index 4e5a574..bf95ec4 100644 --- a/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs +++ b/test/Altinn.Profile.Tests/Testdata/TestDataLoader.cs @@ -6,16 +6,17 @@ namespace Altinn.Profile.Tests.Testdata { public static class TestDataLoader { + private static readonly JsonSerializerOptions _options = new() + { + PropertyNameCaseInsensitive = true + }; + public static async Task Load(string id) { string path = $"../../../Testdata/{typeof(T).Name}/{id}.json"; string fileContent = await File.ReadAllTextAsync(path); - JsonSerializerOptions options = new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }; - - T data = JsonSerializer.Deserialize(fileContent, options); + + T data = JsonSerializer.Deserialize(fileContent, _options); return data; } } From f816c0e6ce40c073342b48e645a1cd50fba60a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Tue, 16 Jan 2024 12:28:25 +0100 Subject: [PATCH 06/10] Added check to identify outcomented authorizations by unittests and fixed outcommented [Authorization] on UsersController --- .../Controllers/UsersController.cs | 2 +- .../IntegrationTests/UserProfileTests.cs | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Altinn.Profile/Controllers/UsersController.cs b/src/Altinn.Profile/Controllers/UsersController.cs index cfc5863..b4b7478 100644 --- a/src/Altinn.Profile/Controllers/UsersController.cs +++ b/src/Altinn.Profile/Controllers/UsersController.cs @@ -16,7 +16,7 @@ namespace Altinn.Profile.Controllers /// /// The users controller /// - /// [Authorize] + [Authorize] [Route("profile/api/v1/users")] [Consumes("application/json")] [Produces("application/json")] diff --git a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs index 69806b0..5e047b5 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs @@ -240,6 +240,44 @@ public async Task GetUsersByUuid_SblBridgeReturnsNotFound_ResponseNotFound() Assert.EndsWith($"users?useruuid={userUuid}", sblRequest.RequestUri.ToString()); } + [Fact] + public async Task GetUsersByUuid_SblBridgeReturnsForbidden_NotAuthorized() + { + // Arrange + const int userId = 20000009; + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage httpRequestMessage = CreateGetRequest(userId, $"/profile/api/v1/users/{userUuid}"); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + } + + [Fact] + public async Task GetUsersByUuid_SblBridgeReturnsUnauthorized_NotAuthenticated() + { + // Arrange + const int userId = 20000009; + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, $"/profile/api/v1/users/{userUuid}"); + + httpRequestMessage.Headers.Add("PlatformAccessToken", PrincipalUtil.GetAccessToken("ttd", "unittest")); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + [Fact] public async Task GetUsersById_SblBridgeReturnsNotFound_ResponseNotFound() { From 95e889861424ce2b8b788ee0ac24332769892d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Tue, 16 Jan 2024 12:35:11 +0100 Subject: [PATCH 07/10] Fixed code smell --- test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs index 5e047b5..c13804c 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs @@ -262,7 +262,6 @@ public async Task GetUsersByUuid_SblBridgeReturnsForbidden_NotAuthorized() public async Task GetUsersByUuid_SblBridgeReturnsUnauthorized_NotAuthenticated() { // Arrange - const int userId = 20000009; Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); HttpRequestMessage httpRequestMessage = new(HttpMethod.Get, $"/profile/api/v1/users/{userUuid}"); From 29562fb0f189799838bb8b58c60c2012ea4b3482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Wed, 17 Jan 2024 10:17:55 +0100 Subject: [PATCH 08/10] Coments on review --- .../Services/Implementation/UserProfilesWrapper.cs | 4 +--- .../UnitTests/UserProfileCachingDecoratorTest.cs | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs b/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs index 19b9fff..fd886e4 100644 --- a/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs +++ b/src/Altinn.Profile/Services/Implementation/UserProfilesWrapper.cs @@ -91,8 +91,6 @@ public async Task GetUser(string ssn) /// public async Task GetUserByUuid(Guid userUuid) { - UserProfile user; - Uri endpointUrl = new Uri($"{_generalSettings.BridgeApiEndpoint}users?useruuid={userUuid}"); HttpResponseMessage response = await _client.GetAsync(endpointUrl); @@ -104,7 +102,7 @@ public async Task GetUserByUuid(Guid userUuid) } string content = await response.Content.ReadAsStringAsync(); - user = JsonSerializer.Deserialize(content, _serializerOptions); + UserProfile user = JsonSerializer.Deserialize(content, _serializerOptions); return user; } diff --git a/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs b/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs index 2528a6e..de44e7b 100644 --- a/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs +++ b/test/Altinn.Profile.Tests/UnitTests/UserProfileCachingDecoratorTest.cs @@ -74,7 +74,7 @@ public async Task GetUserUserUuid_UserInCache_decoratedServiceNotCalled() } /// - /// Tests that the userprofile available in the cache is returned to the caller without forwarding request to decorated service. + /// Tests that the userprofile is not available in the cache call is forwarded to decorated service and cache is populated result returned to caller. /// [Fact] public async Task GetUserUserId_UserNotInCache_decoratedServiceCalledMockPopulated() @@ -99,7 +99,7 @@ public async Task GetUserUserId_UserNotInCache_decoratedServiceCalledMockPopulat } /// - /// Tests that the userprofile available in the cache is returned to the caller without forwarding request to decorated service. + /// Tests that the userprofile is not available in the cache call is forwarded to decorated service and cache is populated result returned to caller. /// [Fact] public async Task GetUserUserUuid_UserNotInCache_decoratedServiceCalledMockPopulated() From b2cfa2bd2513213dd768ea37098627dcc66381dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Wed, 17 Jan 2024 16:07:40 +0100 Subject: [PATCH 09/10] Fixed coments from PR Added Lookup by UserUuid on internal API with tests --- .../UserProfileInternalController.cs | 6 +- .../Models/UserProfileLookup.cs | 9 +- .../UserProfileInternalTests.cs | 101 ++++++++++++++++++ .../IntegrationTests/UserProfileTests.cs | 22 +--- .../Testdata/UserProfile/2001606.json | 2 + .../Testdata/UserProfile/2001607.json | 2 + .../Testdata/UserProfile/2516356.json | 2 + .../Testdata/UserProfile/OrstaECUser.json | 2 + 8 files changed, 124 insertions(+), 22 deletions(-) diff --git a/src/Altinn.Profile/Controllers/UserProfileInternalController.cs b/src/Altinn.Profile/Controllers/UserProfileInternalController.cs index 2cc92c7..27e3cb1 100644 --- a/src/Altinn.Profile/Controllers/UserProfileInternalController.cs +++ b/src/Altinn.Profile/Controllers/UserProfileInternalController.cs @@ -30,9 +30,9 @@ public UserProfileInternalController(IUserProfiles userProfilesWrapper) /// /// Gets the user profile for a given user identified by one of the available types of user identifiers: /// UserId (from Altinn 2 Authn UserProfile) + /// UserUuid (from Altinn 2 Authn UserProfile) /// Username (from Altinn 2 Authn UserProfile) /// SSN/Dnr (from Freg) - /// Uuid (from Altinn 2 Party/UserProfile implementation will be added later) /// /// Input model for providing one of the supported lookup parameters /// User profile of the given user @@ -47,6 +47,10 @@ public async Task> Get([FromBody] UserProfileLookup us { result = await _userProfilesWrapper.GetUser(userProfileLookup.UserId); } + else if (userProfileLookup?.UserUuid != null) + { + result = await _userProfilesWrapper.GetUserByUuid(userProfileLookup.UserUuid.Value); + } else if (!string.IsNullOrWhiteSpace(userProfileLookup?.Username)) { result = await _userProfilesWrapper.GetUserByUsername(userProfileLookup.Username); diff --git a/src/Altinn.Profile/Models/UserProfileLookup.cs b/src/Altinn.Profile/Models/UserProfileLookup.cs index 75fab04..9e5d3e3 100644 --- a/src/Altinn.Profile/Models/UserProfileLookup.cs +++ b/src/Altinn.Profile/Models/UserProfileLookup.cs @@ -1,4 +1,6 @@ -namespace Altinn.Profile.Models +using System; + +namespace Altinn.Profile.Models { /// /// Input model for internal UserProfile lookup requests, where one of the lookup identifiers available must be set for performing the lookup request: @@ -13,6 +15,11 @@ public class UserProfileLookup /// Gets or sets the users UserId if the lookup is to be performed based on this identifier /// public int UserId { get; set; } + + /// + /// Gets or sets the users UserUuid if the lookup is to be performed based on this identifier + /// + public Guid? UserUuid { get; set; } /// /// Gets or sets the users Username if the lookup is to be performed based on this identifier diff --git a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs index 90b4b26..3263a3d 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs @@ -1,3 +1,4 @@ +using System; using System.Net; using System.Net.Http; using System.Net.Http.Json; @@ -76,6 +77,46 @@ public async Task GetUserById_SblBridgeFindsProfile_ResponseOk_ReturnsUserProfil Assert.Equal("nb", actualUser.ProfileSettingPreference.Language); } + [Fact] + public async Task GetUserByUuid_SblBridgeFindsProfile_ResponseOk_ReturnsUserProfile() + { + // Arrange + Guid userUuid = new ("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage sblRequest = null; + DelegatingHandlerStub messageHandler = new(async (request, token) => + { + sblRequest = request; + + UserProfile userProfile = await TestDataLoader.Load(userUuid.ToString()); + return new HttpResponseMessage() { Content = JsonContent.Create(userProfile) }; + }); + _webApplicationFactorySetup.SblBridgeHttpMessageHandler = messageHandler; + + HttpRequestMessage httpRequestMessage = CreatePostRequest($"/profile/api/v1/internal/user/", new UserProfileLookup { UserUuid = userUuid }); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.NotNull(sblRequest); + Assert.Equal(HttpMethod.Get, sblRequest.Method); + Assert.EndsWith($"sblbridge/profile/api/users?useruuid={userUuid}", sblRequest.RequestUri.ToString()); + + string responseContent = await response.Content.ReadAsStringAsync(); + + UserProfile actualUser = JsonSerializer.Deserialize( + responseContent, serializerOptionsCamelCase); + + // These asserts check that deserializing with camel casing was successful. + Assert.Equal(userUuid, actualUser.UserUuid); + Assert.Equal("LEO WILHELMSEN", actualUser.Party.Name); + Assert.Equal("LEO", actualUser.Party.Person.FirstName); + Assert.Equal("nb", actualUser.ProfileSettingPreference.Language); + } + [Fact] public async Task GetUserById_SblBridgeReturnsNotFound_ResponseNotFound() { @@ -106,6 +147,36 @@ public async Task GetUserById_SblBridgeReturnsNotFound_ResponseNotFound() Assert.EndsWith($"sblbridge/profile/api/users/{UserId}", sblRequest.RequestUri.ToString()); } + [Fact] + public async Task GetUserByUuid_SblBridgeReturnsNotFound_ResponseNotFound() + { + // Arrange + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage sblRequest = null; + DelegatingHandlerStub messageHandler = new(async (request, token) => + { + sblRequest = request; + + return await Task.FromResult(new HttpResponseMessage() { StatusCode = HttpStatusCode.NotFound }); + }); + _webApplicationFactorySetup.SblBridgeHttpMessageHandler = messageHandler; + + HttpRequestMessage httpRequestMessage = CreatePostRequest($"/profile/api/v1/internal/user/", new UserProfileLookup { UserUuid = userUuid }); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + + Assert.NotNull(sblRequest); + Assert.Equal(HttpMethod.Get, sblRequest.Method); + Assert.EndsWith($"sblbridge/profile/api/users?useruuid={userUuid}", sblRequest.RequestUri.ToString()); + } + [Fact] public async Task GetUserById_SblBridgeReturnsUnavailable_ResponseNotFound() { @@ -136,6 +207,36 @@ public async Task GetUserById_SblBridgeReturnsUnavailable_ResponseNotFound() Assert.EndsWith($"sblbridge/profile/api/users/{UserId}", sblRequest.RequestUri.ToString()); } + [Fact] + public async Task GetUserByUuid_SblBridgeReturnsUnavailable_ResponseNotFound() + { + // Arrange + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + + HttpRequestMessage sblRequest = null; + DelegatingHandlerStub messageHandler = new(async (request, token) => + { + sblRequest = request; + + return await Task.FromResult(new HttpResponseMessage() { StatusCode = HttpStatusCode.ServiceUnavailable }); + }); + _webApplicationFactorySetup.SblBridgeHttpMessageHandler = messageHandler; + + HttpRequestMessage httpRequestMessage = CreatePostRequest($"/profile/api/v1/internal/user/", new UserProfileLookup { UserUuid = userUuid }); + + HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); + + // Act + HttpResponseMessage response = await client.SendAsync(httpRequestMessage); + + // Assert + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + + Assert.NotNull(sblRequest); + Assert.Equal(HttpMethod.Get, sblRequest.Method); + Assert.EndsWith($"sblbridge/profile/api/users?useruuid={userUuid}", sblRequest.RequestUri.ToString()); + } + [Fact] public async Task GetUserBySsn_SblBridgeFindsProfile_ReturnsUserProfile() { diff --git a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs index c13804c..692fd23 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileTests.cs @@ -190,7 +190,7 @@ public async Task GetUsersByUuid_SblBridgeFindsProfile_ResponseOk_ReturnsUserPro } [Fact] - public async Task GetUsersByUuid_SblBridgeFindsProfile_NotAuthorized_ReturnsForbidden() + public async Task GetUsersByUuid_UserAuthenticatedMissingPlatformAccesToken_ReturnsForbidden() { // Arrange const int userId = 20000009; @@ -241,25 +241,7 @@ public async Task GetUsersByUuid_SblBridgeReturnsNotFound_ResponseNotFound() } [Fact] - public async Task GetUsersByUuid_SblBridgeReturnsForbidden_NotAuthorized() - { - // Arrange - const int userId = 20000009; - Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); - - HttpRequestMessage httpRequestMessage = CreateGetRequest(userId, $"/profile/api/v1/users/{userUuid}"); - - HttpClient client = _webApplicationFactorySetup.GetTestServerClient(); - - // Act - HttpResponseMessage response = await client.SendAsync(httpRequestMessage); - - // Assert - Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); - } - - [Fact] - public async Task GetUsersByUuid_SblBridgeReturnsUnauthorized_NotAuthenticated() + public async Task GetUsersByUuid_MissingAuthentication_NotAuthorized() { // Arrange Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); diff --git a/test/Altinn.Profile.Tests/Testdata/UserProfile/2001606.json b/test/Altinn.Profile.Tests/Testdata/UserProfile/2001606.json index 74e7364..d4cb0a4 100644 --- a/test/Altinn.Profile.Tests/Testdata/UserProfile/2001606.json +++ b/test/Altinn.Profile.Tests/Testdata/UserProfile/2001606.json @@ -1,5 +1,6 @@ { "UserId": 2001606, + "UserUUID": "1a131a3b-c6c9-4572-86fd-dfe36c3de06a", "UserType": 1, "UserName": "", "PhoneNumber": null, @@ -30,6 +31,7 @@ }, "Organization": null, "PartyId": 50002113, + "PartyUUID": "1a131a3b-c6c9-4572-86fd-dfe36c3de06a", "UnitType": null, "Name": "TUVA LANDRO", "IsDeleted": false, diff --git a/test/Altinn.Profile.Tests/Testdata/UserProfile/2001607.json b/test/Altinn.Profile.Tests/Testdata/UserProfile/2001607.json index fb33d2f..2e4913f 100644 --- a/test/Altinn.Profile.Tests/Testdata/UserProfile/2001607.json +++ b/test/Altinn.Profile.Tests/Testdata/UserProfile/2001607.json @@ -1,5 +1,6 @@ { "UserId": 2001607, + "UserUUID": "db8eafc0-6056-43b5-b047-4adcd84f659c", "UserType": 1, "UserName": "", "PhoneNumber": null, @@ -30,6 +31,7 @@ }, "Organization": null, "PartyId": 50002113, + "PartyUUID": "db8eafc0-6056-43b5-b047-4adcd84f659c", "UnitType": null, "Name": "TUVA LANDRO", "IsDeleted": false, diff --git a/test/Altinn.Profile.Tests/Testdata/UserProfile/2516356.json b/test/Altinn.Profile.Tests/Testdata/UserProfile/2516356.json index f49abad..df20193 100644 --- a/test/Altinn.Profile.Tests/Testdata/UserProfile/2516356.json +++ b/test/Altinn.Profile.Tests/Testdata/UserProfile/2516356.json @@ -1,11 +1,13 @@ { "UserId": 2516356, + "UserUUID": "4f4e31b5-0e4f-400c-b89d-551fe2385d9f", "UserName": "sophie", "PhoneNumber": "90001337", "Email": "2516356@altinnstudiotestusers.com", "PartyId": 5780927, "Party": { "PartyId": 5780927, + "PartyUUID": "4f4e31b5-0e4f-400c-b89d-551fe2385d9f", "Name": "Sophie Salt", "SSN": "01017512345", "Person": { diff --git a/test/Altinn.Profile.Tests/Testdata/UserProfile/OrstaECUser.json b/test/Altinn.Profile.Tests/Testdata/UserProfile/OrstaECUser.json index bb5173a..35925eb 100644 --- a/test/Altinn.Profile.Tests/Testdata/UserProfile/OrstaECUser.json +++ b/test/Altinn.Profile.Tests/Testdata/UserProfile/OrstaECUser.json @@ -1,5 +1,6 @@ { "UserId": 2001072, + "UserUUID": "34b62493-84c6-4794-bf91-6cd23ead761c", "UserType": 3, "UserName": "OrstaECUser", "ExternalIdentity": "", @@ -29,6 +30,7 @@ "UnitStatus": "N" }, "PartyId": 50005545, + "PartyUUID": "ec061efa-4c2a-4dbd-87f5-bcb59cdeaf91", "UnitType": "AS", "Name": "ORSTA OG HEGGEDAL ", "IsDeleted": false, From 83826612800dbce3fd5f5ec8c1255fb09b417d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remi=20L=C3=B8voll?= Date: Wed, 17 Jan 2024 16:13:43 +0100 Subject: [PATCH 10/10] Fixed code issue --- .../IntegrationTests/UserProfileInternalTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs index 3263a3d..192d342 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/UserProfileInternalTests.cs @@ -81,7 +81,7 @@ public async Task GetUserById_SblBridgeFindsProfile_ResponseOk_ReturnsUserProfil public async Task GetUserByUuid_SblBridgeFindsProfile_ResponseOk_ReturnsUserProfile() { // Arrange - Guid userUuid = new ("cc86d2c7-1695-44b0-8e82-e633243fdf31"); + Guid userUuid = new("cc86d2c7-1695-44b0-8e82-e633243fdf31"); HttpRequestMessage sblRequest = null; DelegatingHandlerStub messageHandler = new(async (request, token) =>