< Summary

Information
Line coverage
64%
Covered lines: 50
Uncovered lines: 28
Coverable lines: 78
Total lines: 156
Line coverage: 64.1%
Branch coverage
64%
Covered branches: 9
Total branches: 14
Branch coverage: 64.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetUserAsync()50%2.29258.33%
RegisterUserAsync()75%4.29473.68%
ValidateUserAsync()75%4.41470.58%
GetAllUsersAsync()100%210%
UpdateUserAsync()50%4.34472.22%

File(s)

/home/runner/work/SEP4/SEP4/backend/microservices/autorisering/WebApi/DAO/UserDAO.cs

#LineLine coverage
 1using System.Text.RegularExpressions;
 2using MongoDB.Bson;
 3using MongoDB.Driver;
 4using WebApi.DAO;
 5using WebApi.Models;
 6using System.Data;
 7
 8
 9public class UserDAO : IUserDAO
 10{
 11    private readonly IMongoCollection<User> _userMongoCollection;
 12
 513    public UserDAO(MongoDbContext context)
 514    {
 515        _userMongoCollection = context.Database.GetCollection<User>("UserData");
 516    }
 17
 18    public async Task<User> GetUserAsync(string username)
 219    {
 20        try
 221        {
 22            // Use a regular expression with case-insensitive search
 223            var filter = Builders<User>.Filter.Regex(u => u.Username, new BsonRegularExpression(username, "i"));
 224            var user = await _userMongoCollection.Find(filter).FirstOrDefaultAsync();
 25
 226            if (user == null)
 027            {
 028                throw new KeyNotFoundException($"User with username {username} not found.");
 29            }
 30
 231            return user;
 32        }
 033        catch (Exception ex)
 034        {
 035            throw new Exception($"An error occurred when retrieving user: {ex.Message}", ex);
 36        }
 237    }
 38
 39
 40    public async Task RegisterUserAsync(User user)
 641    {
 42        try
 643        {
 644            if (user == null)
 045            {
 046                throw new ArgumentNullException(nameof(user));
 47            }
 48
 49            // Check for duplicate data
 650            var filter = Builders<User>.Filter.Regex(u => u.Username, new BsonRegularExpression($"^{Regex.Escape(user.Us
 651            var duplicateData = await _userMongoCollection.Find(filter).FirstOrDefaultAsync();
 652            if (duplicateData != null)
 153            {
 154                throw new Exception("Something went wrong."); // Vague response to make it harder for hackers
 55            }
 56
 57            // Add data to the collection
 558            await _userMongoCollection.InsertOneAsync(user);
 559        }
 060        catch (DuplicateNameException)
 061        {
 62            // Rethrow this exception directly without additional wrapping
 063            throw;
 64        }
 165        catch (Exception ex)
 166        {
 167            throw new Exception("Failed to register user: " + ex.Message, ex);
 68        }
 569    }
 70
 71
 72    public async Task<User> ValidateUserAsync(string username, string password)
 273    {
 74        try
 275        {
 76            // Attempt to retrieve the user by username (case-insensitive)
 277            var filter = Builders<User>.Filter.Regex(u => u.Username, new BsonRegularExpression($"^{username}$", "i"));
 278            var user = await _userMongoCollection.Find(filter).FirstOrDefaultAsync();
 79
 80            // If no user is found, or the password does not match, throw an exception
 281            if (user == null)
 082            {
 083                throw new UnauthorizedAccessException("Username is incorrect.");
 84            }
 85
 386            if (user.Password != password) {
 187                throw new UnauthorizedAccessException("Password is incorrect.");
 88            }
 89
 90            // If user is found and password matches, return the user object
 191            return user;
 92        }
 193        catch (UnauthorizedAccessException)
 194        {
 95            // Re-throw specific exceptions to be handled or tested appropriately
 196            throw;
 97        }
 098        catch (Exception ex)
 099        {
 100            // Optionally, log and handle unexpected exceptions here, or wrap them if there's a good reason
 0101            throw new Exception($"An unexpected error occurred when validating user: {ex.Message}", ex);
 102        }
 1103    }
 104
 105    public async Task<List<User>> GetAllUsersAsync()
 0106    {
 107        try
 0108        {
 109            // Define a sort by 'Role' in ascending order
 0110            var sortByRole = Builders<User>.Sort.Ascending(u => u.Role);
 111
 112            // Retrieve all users from the collection and sort them by 'Role'
 0113            return await _userMongoCollection.Find(new BsonDocument()).Sort(sortByRole).ToListAsync();
 114        }
 0115        catch (Exception ex)
 0116        {
 117            // Handle or log the exception as needed
 0118            throw new Exception($"Failed to retrieve all users sorted by role: {ex.Message}", ex);
 119        }
 120
 0121    }
 122
 123    public async Task<User> UpdateUserAsync(User user)
 1124  {
 125       try
 1126      {
 127          // Create a filter to match the user by username (which remains unchanged)
 1128          var filter = Builders<User>.Filter.Eq(userData => userData.Username, user.Username);
 129
 130          // Create an update definition to set new values for all updatable fields
 1131          var updateDefinition = Builders<User>.Update
 1132              .Set(userData => userData.Password, user.Password)
 1133              .Set(userData => userData.Email, user.Email)
 1134              .Set(userData => userData.Role, user.Role)
 1135              .Set(userData => userData.Age, user.Age);  // Add more fields as necessary
 136
 137          // Perform the update operation
 1138          var result = await _userMongoCollection.UpdateOneAsync(filter, updateDefinition);
 139
 140          // Check if the update was successful, if not, handle it appropriately
 1141          if (result.MatchedCount == 0)
 0142              throw new KeyNotFoundException($"No user found with username {user.Username}");
 1143          if (result.ModifiedCount == 0)
 0144              throw new Exception("No changes were made during the update operation.");
 145
 146          // Return the updated user data - consider fetching the user again if accurate data is needed
 1147          return user;
 148      }
 0149      catch (Exception ex)
 0150      {
 0151          throw new Exception($"Failed to update user: {ex.Message}", ex);
 152      }
 1153  }
 154
 155
 156}