diff --git a/mohaymen-codestar-Team02.sln b/mohaymen-codestar-Team02.sln index f7305f0..d0f7ce7 100644 --- a/mohaymen-codestar-Team02.sln +++ b/mohaymen-codestar-Team02.sln @@ -1,5 +1,4 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mohaymen-codestar-Team02", "mohaymen-codestar-Team02\mohaymen-codestar-Team02.csproj", "{4D1C173E-6901-406B-AF51-8272236E98FA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mohaymen-codestar-Team02_XUnitTest", "mohaymen-codestar-Team02_XUnitTest\mohaymen-codestar-Team02_XUnitTest.csproj", "{DBCC3406-305C-4B21-AF94-8BF8B78D1040}" @@ -18,5 +17,9 @@ Global {DBCC3406-305C-4B21-AF94-8BF8B78D1040}.Debug|Any CPU.Build.0 = Debug|Any CPU {DBCC3406-305C-4B21-AF94-8BF8B78D1040}.Release|Any CPU.ActiveCfg = Release|Any CPU {DBCC3406-305C-4B21-AF94-8BF8B78D1040}.Release|Any CPU.Build.0 = Release|Any CPU + {28E49A9C-03AF-4843-9757-57D7E096B686}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28E49A9C-03AF-4843-9757-57D7E096B686}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28E49A9C-03AF-4843-9757-57D7E096B686}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28E49A9C-03AF-4843-9757-57D7E096B686}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/mohaymen-codestar-Team02/Controllers/AdminController.cs b/mohaymen-codestar-Team02/Controllers/AdminController.cs index 93cb711..706804a 100644 --- a/mohaymen-codestar-Team02/Controllers/AdminController.cs +++ b/mohaymen-codestar-Team02/Controllers/AdminController.cs @@ -43,7 +43,7 @@ public async Task Register([FromBody] RegisterUserDto request) Username = request.Username, FirstName = request.FirstName, LastName = request.LastName, - Email = request.Email, + Email = request.Email }; ServiceResponse response = diff --git a/mohaymen-codestar-Team02/Controllers/AuthenticationController.cs b/mohaymen-codestar-Team02/Controllers/AuthenticationController.cs index de21eb1..b168070 100644 --- a/mohaymen-codestar-Team02/Controllers/AuthenticationController.cs +++ b/mohaymen-codestar-Team02/Controllers/AuthenticationController.cs @@ -4,7 +4,6 @@ using mohaymen_codestar_Team02.Models; using mohaymen_codestar_Team02.Services.Authenticatoin; - namespace mohaymen_codestar_Team02.Controllers; [ApiController] diff --git a/mohaymen-codestar-Team02/Controllers/DataAdminController.cs b/mohaymen-codestar-Team02/Controllers/DataAdminController.cs new file mode 100644 index 0000000..f598ef3 --- /dev/null +++ b/mohaymen-codestar-Team02/Controllers/DataAdminController.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Mvc; +using mohaymen_codestar_Team02.Dto.StoreDataDto; +using mohaymen_codestar_Team02.Services.DataAdminService; +using mohaymen_codestar_Team02.Services.FileReaderService; + +namespace mohaymen_codestar_Team02.Controllers; + +public class DataAdminController : ControllerBase +{ + + private readonly IDataAdminService _dataAdminService; + private readonly IFileReader _fileReader; + public DataAdminController(IDataAdminService dataAdminService, IFileReader fileReader) + { + _dataAdminService = dataAdminService; + _fileReader = fileReader; + } + [HttpPost("DataSets")] + public async Task StoreNewDataSet([FromForm] StoreDataDto storeDataDto) + { + var edgeFile = _fileReader.Read(storeDataDto.EdgeFile); + var vertexFile = _fileReader.Read(storeDataDto.VertexFile); + var response = await _dataAdminService.StoreData(edgeFile, vertexFile, storeDataDto.DataName, + Path.GetFileName(storeDataDto.EdgeFile.FileName), Path.GetFileName(storeDataDto.VertexFile.FileName), + storeDataDto.CreatorUserName); + return StatusCode((int)response.Type, response); + } + + [HttpGet("DataSets")] + public void GetDataSetsList() + { + } + + [HttpGet("DataSets/{dataSetName}")] + public void DisplayDataSetAsGraph(string dataSetName) + { + } + + [HttpGet("DataSets/{dataSetName}/Vertices/{vertexId}")] + public void DisplayVertexDetails(string datasetName, int vertexId) + { + } + + [HttpGet("DataSets/{dataSetName}/Edges/{edgeId}")] + public void DisplayEdgeDetails(string datasetName, int edgeId) + { + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Data/DataContext.cs b/mohaymen-codestar-Team02/Data/DataContext.cs index f6ee4d7..245b3ec 100644 --- a/mohaymen-codestar-Team02/Data/DataContext.cs +++ b/mohaymen-codestar-Team02/Data/DataContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; using mohaymen_codestar_Team02.Models; +using mohaymen_codestar_Team02.Models.EdgeEAV; +using mohaymen_codestar_Team02.Models.VertexEAV; namespace mohaymen_codestar_Team02.Data; @@ -12,6 +14,14 @@ public DataContext(DbContextOptions options) : base(options) public DbSet Users { get; set; } public DbSet Roles { get; set; } public DbSet UserRoles { get; set; } + public DbSet VertexEntities { get; set; } + public DbSet EdgeEntities { get; set; } + public DbSet VertexAttributes { get; set; } + public DbSet EdgeAttributes { get; set; } + public DbSet VertexValues { get; set; } + public DbSet EdgeValues { get; set; } + public DbSet DataSets { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/mohaymen-codestar-Team02/Dto/StoreDataDto/StoreDataDto.cs b/mohaymen-codestar-Team02/Dto/StoreDataDto/StoreDataDto.cs new file mode 100644 index 0000000..052bb7b --- /dev/null +++ b/mohaymen-codestar-Team02/Dto/StoreDataDto/StoreDataDto.cs @@ -0,0 +1,11 @@ +namespace mohaymen_codestar_Team02.Dto.StoreDataDto; + +public class StoreDataDto +{ + public IFormFile EdgeFile { get; set; } + public IFormFile VertexFile { get; set; } + public string FileType { get; set; } + public string DataName { get; set; } + + public string CreatorUserName { get; set; } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/DataGroup.cs b/mohaymen-codestar-Team02/Models/DataGroup.cs new file mode 100644 index 0000000..169041b --- /dev/null +++ b/mohaymen-codestar-Team02/Models/DataGroup.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Diagnostics; +using mohaymen_codestar_Team02.Models.EdgeEAV; +using mohaymen_codestar_Team02.Models.VertexEAV; + +namespace mohaymen_codestar_Team02.Models; + +public class DataGroup +{ + public DataGroup(string name, long userId) + { + Name = name; + UserId = userId; + } + [Key] public long DataGroupId { get; set; } + + public string Name { get; set; } + public DateTime CreateAt { get; set; } = DateTime.UtcNow; + public DateTime UpdateAt { get; set; } = DateTime.UtcNow; + + public virtual EdgeEntity EdgeEntity { get; set; } + public virtual VertexEntity VertexEntity { get; set; } + + public long UserId { get; set; } + + [ForeignKey("UserId")] public virtual User? User { get; set; } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeAttribute.cs b/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeAttribute.cs new file mode 100644 index 0000000..af53cc9 --- /dev/null +++ b/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeAttribute.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace mohaymen_codestar_Team02.Models.EdgeEAV; + +public class EdgeAttribute +{ + public EdgeAttribute(string name, long edgeEntityId) + { + Name = name; + EdgeEntityId = edgeEntityId; + } + [Key] public long Id { get; set; } + public string Name { get; set; } + public long EdgeEntityId { get; set; } + [ForeignKey("EdgeEntityId")] public virtual EdgeEntity EdgeEntity { get; set; } + public virtual ICollection EdgeValues { get; set; } = new List(); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeEntity.cs b/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeEntity.cs new file mode 100644 index 0000000..2409d03 --- /dev/null +++ b/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeEntity.cs @@ -0,0 +1,34 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text.RegularExpressions; + +namespace mohaymen_codestar_Team02.Models.EdgeEAV; + +public class EdgeEntity +{ + public EdgeEntity(string name, long dataGroupId) + { + _name = name + "!Edge" + "!" + Guid.NewGuid() + "!"; + DataGroupId = dataGroupId; + } + + [Key] public long Id { get; set; } + private string _name; + + public string Name + { + get + { + var regex = new Regex(@"^(.+?)!"); + var match = regex.Match(_name); + if (match.Success) return match.Groups[1].Value; + + return null; + } + set => _name = value + "!Edge" + "!" + Guid.NewGuid() + "!"; + } + + public long DataGroupId { get; set; } + [ForeignKey("DataGroupId")] public virtual DataGroup? DataGroup { get; set; } + public virtual ICollection EdgeAttributes { get; set; } = new List(); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeValue.cs b/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeValue.cs new file mode 100644 index 0000000..5caa070 --- /dev/null +++ b/mohaymen-codestar-Team02/Models/EdgeEAV/EdgeValue.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace mohaymen_codestar_Team02.Models.EdgeEAV; + +public class EdgeValue +{ + public EdgeValue(string stringValue, long edgeAttributeId, string objectId) + { + StringValue = stringValue; + EdgeAttributeId = edgeAttributeId; + ObjectId = objectId; + } + [Key] public long Id { get; set; } + public string StringValue { get; set; } + public long EdgeAttributeId { get; set; } + [ForeignKey("EdgeAttributeId")] public virtual EdgeAttribute EdgeAttribute { get; set; } + public string ObjectId { get; set; } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/ServiceResponse.cs b/mohaymen-codestar-Team02/Models/ServiceResponse.cs index 91cea0f..712fcb4 100644 --- a/mohaymen-codestar-Team02/Models/ServiceResponse.cs +++ b/mohaymen-codestar-Team02/Models/ServiceResponse.cs @@ -2,14 +2,14 @@ namespace mohaymen_codestar_Team02.Models; public class ServiceResponse { - public ServiceResponse(T data, ApiResponseType type, string message) + public ServiceResponse(T? data, ApiResponseType type, string message) { Data = data; Type = type; Message = message; } - public T Data { get; set; } + public T? Data { get; set; } public ApiResponseType Type { get; set; } public string Message { get; set; } } \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/User.cs b/mohaymen-codestar-Team02/Models/User.cs index 5e8614b..de733c4 100644 --- a/mohaymen-codestar-Team02/Models/User.cs +++ b/mohaymen-codestar-Team02/Models/User.cs @@ -20,4 +20,5 @@ public class User [Required][StringLength(256)] public byte[] PasswordHash { get; set; } public virtual ICollection UserRoles { get; set; } + public virtual ICollection DataSets { get; set; } } \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/UserRole.cs b/mohaymen-codestar-Team02/Models/UserRole.cs index ec4fb40..443455c 100644 --- a/mohaymen-codestar-Team02/Models/UserRole.cs +++ b/mohaymen-codestar-Team02/Models/UserRole.cs @@ -1,6 +1,6 @@ -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using mohaymen_codestar_Team02.Models; + +namespace mohaymen_codestar_Team02.Models; public class UserRole { diff --git a/mohaymen-codestar-Team02/Models/VertexEAV/VertexAttribute.cs b/mohaymen-codestar-Team02/Models/VertexEAV/VertexAttribute.cs new file mode 100644 index 0000000..f814d90 --- /dev/null +++ b/mohaymen-codestar-Team02/Models/VertexEAV/VertexAttribute.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using mohaymen_codestar_Team02.Models.EdgeEAV; + +namespace mohaymen_codestar_Team02.Models.VertexEAV; + +public class VertexAttribute +{ + public VertexAttribute(string name, long vertexEntityId) + { + Name = name; + VertexEntityId = vertexEntityId; + } + [Key] public long Id { get; set; } + public string Name { get; set; } + public long VertexEntityId { get; set; } + [ForeignKey("VertexEntityId")] public virtual VertexEntity VertexEntity { get; set; } + public virtual ICollection VertexValues { get; set; } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/VertexEAV/VertexEntity.cs b/mohaymen-codestar-Team02/Models/VertexEAV/VertexEntity.cs new file mode 100644 index 0000000..39e731b --- /dev/null +++ b/mohaymen-codestar-Team02/Models/VertexEAV/VertexEntity.cs @@ -0,0 +1,45 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text.RegularExpressions; +using mohaymen_codestar_Team02.Models.EdgeEAV; + +namespace mohaymen_codestar_Team02.Models.VertexEAV; + +public class VertexEntity +{ + public VertexEntity(string name, long dataGroupId) + { + if (!name.Contains("!")) + { + _name = name + "!vertex" + "!" + Guid.NewGuid() + "!"; + DataGroupId = dataGroupId; + } + else + { + throw new ArgumentException("your name contain !"); + } + } + + [Key] public long Id { get; set; } + private string _name; + + public string Name + { + get + { + var regex = new Regex(@"^(.+?)!"); + var match = regex.Match(_name); + if (match.Success) return match.Groups[1].Value; + + return null; + } + set + { + if (!value.Contains("!")) _name = value + "!vertex" + "!" + Guid.NewGuid() + "!"; + } + } + + public long DataGroupId { get; set; } + [ForeignKey("DataGroupId")] public virtual DataGroup DataGroup { get; set; } + public virtual ICollection VertexAttributes { get; set; } = new List(); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Models/VertexEAV/VertexValue.cs b/mohaymen-codestar-Team02/Models/VertexEAV/VertexValue.cs new file mode 100644 index 0000000..0aad88e --- /dev/null +++ b/mohaymen-codestar-Team02/Models/VertexEAV/VertexValue.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using mohaymen_codestar_Team02.Models.EdgeEAV; + +namespace mohaymen_codestar_Team02.Models.VertexEAV; + +public class VertexValue +{ + + public VertexValue(string stringValue, long vertexAttributeId, string objectId) + { + StringValue = stringValue; + VertexAttributeId = vertexAttributeId; + ObjectId = objectId; + } + [Key] public long Id { get; set; } + public string StringValue { get; set; } + + public long VertexAttributeId { get; set; } + [ForeignKey("VertexAttributeId")] public virtual VertexAttribute VertexAttribute { get; set; } + public string ObjectId { get; set; } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/Administration/AdminService.cs b/mohaymen-codestar-Team02/Services/Administration/AdminService.cs index bfecb77..b43ddd4 100644 --- a/mohaymen-codestar-Team02/Services/Administration/AdminService.cs +++ b/mohaymen-codestar-Team02/Services/Administration/AdminService.cs @@ -98,7 +98,7 @@ public async Task>> GetAllRoles() if (await UserExists(user.Username)) return new ServiceResponse(null, ApiResponseType.Conflict, Resources.UserAlreadyExistsMessage); - _passwordService.CreatePasswordHash(password, out byte[] passwordHash, out byte[] passwordSalt); + _passwordService.CreatePasswordHash(password, out var passwordHash, out var passwordSalt); user.PasswordHash = passwordHash; user.Salt = passwordSalt; @@ -165,7 +165,7 @@ public async Task>> GetAllRoles() if (await GetUserRole(foundRole, foundUser) is not null) return new ServiceResponse(null, ApiResponseType.BadRequest, Resources.RoleAlreadyAssigned); - UserRole userRole = new UserRole + var userRole = new UserRole { Role = foundRole, User = foundUser, @@ -238,7 +238,6 @@ private Task IsAdmin(User? user) return await _context.Roles.FirstOrDefaultAsync(x => x.RoleType.ToLower() == roleType.ToLower()); } - private async Task GetUserRole(Role foundRole, User foundUser) => await _context.UserRoles.FirstOrDefaultAsync(x => x.User.Username != null && foundUser.Username != null && x.RoleId == foundRole.RoleId && diff --git a/mohaymen-codestar-Team02/Services/Authenticatoin/AuthenticationService.cs b/mohaymen-codestar-Team02/Services/Authenticatoin/AuthenticationService.cs index c3ce437..4ddb425 100644 --- a/mohaymen-codestar-Team02/Services/Authenticatoin/AuthenticationService.cs +++ b/mohaymen-codestar-Team02/Services/Authenticatoin/AuthenticationService.cs @@ -44,7 +44,7 @@ public AuthenticationService(DataContext context, ICookieService cookieService, Claim[] claims = new[] { - new Claim(ClaimTypes.Name, user.Username), + new Claim(ClaimTypes.Name, user.Username) }; _cookieService.CreateCookie(_tokenService.CreateToken(claims)); diff --git a/mohaymen-codestar-Team02/Services/DataAdminService/DataAdminService.cs b/mohaymen-codestar-Team02/Services/DataAdminService/DataAdminService.cs new file mode 100644 index 0000000..af0820a --- /dev/null +++ b/mohaymen-codestar-Team02/Services/DataAdminService/DataAdminService.cs @@ -0,0 +1,50 @@ +using mohaymen_codestar_Team02.Models; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +namespace mohaymen_codestar_Team02.Services.DataAdminService; + +public class DataAdminService + : IDataAdminService +{ + private readonly IStorHandler storHandler; + public DataAdminService(IStorHandler storHandler) + { + this.storHandler = storHandler; + } + public async Task> StoreData(string? edgeFile, string? vertexFile, string graphName + , string? edgeEntityName, string vertexEntityName, string userName) + { + if (string.IsNullOrEmpty(edgeEntityName) || string.IsNullOrEmpty(graphName) || + string.IsNullOrEmpty(vertexEntityName)) + return new ServiceResponse(string.Empty, ApiResponseType.BadRequest, Data.Resources.InvalidInpute); + + var dataGroupId = await storHandler.StoreDataSet(graphName, userName); + if (dataGroupId == -1) + return new ServiceResponse(string.Empty, ApiResponseType.BadRequest, Data.Resources.InvalidInpute); + + if (!await storHandler.EdageStorer.StoreFileData(edgeEntityName, edgeFile, dataGroupId)) + return new ServiceResponse(string.Empty, + ApiResponseType.BadRequest, Data.Resources.InvalidInpute); + + if (!await storHandler.VertexStorer.StoreFileData(vertexEntityName, vertexFile, dataGroupId)) + return new ServiceResponse(string.Empty, + ApiResponseType.BadRequest, Data.Resources.InvalidInpute); + + return new ServiceResponse(null, ApiResponseType.Success, string.Empty); + } + + public Task> DisplayDataSet() + { + throw new NotImplementedException(); + } + + public Task> DisplayVertexData() + { + throw new NotImplementedException(); + } + + public Task> DisplayEdgeData() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/DataAdminService/IDataAdminService.cs b/mohaymen-codestar-Team02/Services/DataAdminService/IDataAdminService.cs new file mode 100644 index 0000000..234e7f5 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/DataAdminService/IDataAdminService.cs @@ -0,0 +1,13 @@ +using mohaymen_codestar_Team02.Models; + +namespace mohaymen_codestar_Team02.Services.DataAdminService; + +public interface IDataAdminService +{ + Task> StoreData(string? edgeFile, string? vertexFile, string graphName + , string? edgeEntityName, string vertexEntityName, string userName); + + Task> DisplayDataSet(); + Task> DisplayVertexData(); + Task> DisplayEdgeData(); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/DisplayData/DisplayService.cs b/mohaymen-codestar-Team02/Services/DisplayData/DisplayService.cs new file mode 100644 index 0000000..000b080 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/DisplayData/DisplayService.cs @@ -0,0 +1,113 @@ +using Microsoft.EntityFrameworkCore; +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Services.TokenService; +using QuikGraph; + +namespace mohaymen_codestar_Team02.Services; + +public class DisplayService +{ + private readonly DataContext _context; + private readonly ModelBuilder _modelBuilder; + private readonly ObjectBuilder _objectBuilder; + + public DisplayService(DataContext context, ModelBuilder modelBuilder, ObjectBuilder objectBuilder) + { + _context = context; + _modelBuilder = modelBuilder; + _objectBuilder = objectBuilder; + } + + public void GetGraph(string databaseName, string sourceEdgeIdentifierFieldName, + string destinationEdgeIdentifierFieldName, string vertexIdentifierFieldName, bool directed, + out List vertices, List edges) + { + // get dataset + var dataSet = _context.DataSets.Include(ds => ds.VertexEntity) + .ThenInclude(ve => ve.VertexAttributes).ThenInclude(vv => vv.VertexValues).Include(ds => ds.EdgeEntity) + .ThenInclude(ee => ee.EdgeAttributes).ThenInclude(ev => ev.EdgeValues) + .FirstOrDefault(ds => ds.Name.ToLower().Equals(databaseName.ToLower())); + + // get vertex info + var vertexTypeName = dataSet.VertexEntity.Name; + + var vertexFieldNames = dataSet.VertexEntity.VertexAttributes.Select(a => a.Name).ToList(); + + var vertexRecords = dataSet.VertexEntity.VertexAttributes.Select(a => a.VertexValues).SelectMany(v => v) + .GroupBy(v => v.ObjectId) + .Select(g => g.ToDictionary(v => v.VertexAttribute.Name, v => v.StringValue)).ToList(); + + var vertexFieldNamesTypes = new Dictionary(); + foreach (var vertexFieldNameType in vertexFieldNames) + { + vertexFieldNamesTypes.Add(vertexFieldNameType, typeof(string)); + } + + var vertexType = _modelBuilder.CreateDynamicClass(vertexTypeName, vertexFieldNamesTypes, null); + + vertices = new List(); // + foreach (var vertexRecord in vertexRecords) + { + vertices.Add(_objectBuilder.CreateDynamicObject(vertexType, vertexRecord)); + } + + + // get edge info + var edgeTypeName = dataSet.EdgeEntity.Name; + var EdgeFieldNames = dataSet.EdgeEntity.EdgeAttributes.Select(a => a.Name).ToList(); + var edgeRecords = dataSet.EdgeEntity.EdgeAttributes.Select(ea => ea.EdgeValues).SelectMany(v => v) + .GroupBy(v => v.ObjectId) + .Select(g => g.ToDictionary(v => v.EdgeAttribute.Name, v => v.StringValue)).ToList(); + + // delete from field names + var edgeFieldNameTypes = new Dictionary(); // + + edgeFieldNameTypes.Add("Source", vertexType); + edgeFieldNameTypes.Add("Target", vertexType); + + foreach (var edgeFieldNameType in EdgeFieldNames) + { + edgeFieldNameTypes.Add(edgeFieldNameType, typeof(string)); + } + + var vertexType1 = typeof(IEdge<>).MakeGenericType(vertexType); + var edgeType = _modelBuilder.CreateDynamicClass(edgeTypeName, edgeFieldNameTypes, vertexType1); + + edges = new List(); // + // get valid edgges + List> sources = new List>(); + List> destinations = new List>(); + + foreach (var er in edgeRecords) + { + foreach (var vr in vertexRecords) + { + if (vr[vertexIdentifierFieldName].Equals(er[sourceEdgeIdentifierFieldName])) + { + sources.Add(vr); + } + + if (vr[vertexIdentifierFieldName].Equals(er[destinationEdgeIdentifierFieldName])) + { + destinations.Add(vr); + } + } + + if (sources.Count != 0 || destinations.Count != 0) + { + // error + } + else + { + // create edges + foreach (var source in sources) + { + foreach (var destination in destinations) + { + edges.Add(_objectBuilder.CreateDynamicObject1(edgeType, er, vertexType, source, destination)); + } + } + } + } + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/DisplayData/IDisplayDataService.cs b/mohaymen-codestar-Team02/Services/DisplayData/IDisplayDataService.cs new file mode 100644 index 0000000..e6f3388 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/DisplayData/IDisplayDataService.cs @@ -0,0 +1,10 @@ +using mohaymen_codestar_Team02.Models; + +namespace mohaymen_codestar_Team02.Services; + +public interface IDisplayDataService +{ + ServiceResponse DisplayGraph(); + ServiceResponse DisplayVertex(); + ServiceResponse DisplayEdge(); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/FileReaderService/IFileReader.cs b/mohaymen-codestar-Team02/Services/FileReaderService/IFileReader.cs new file mode 100644 index 0000000..a22b1e3 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/FileReaderService/IFileReader.cs @@ -0,0 +1,6 @@ +namespace mohaymen_codestar_Team02.Services.FileReaderService; + +public interface IFileReader +{ + string Read(IFormFile? formFile); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/FileReaderService/ReadCsvFile.cs b/mohaymen-codestar-Team02/Services/FileReaderService/ReadCsvFile.cs new file mode 100644 index 0000000..0a09edd --- /dev/null +++ b/mohaymen-codestar-Team02/Services/FileReaderService/ReadCsvFile.cs @@ -0,0 +1,14 @@ +namespace mohaymen_codestar_Team02.Services.FileReaderService; + +public class ReadCsvFile : IFileReader +{ + public string Read(IFormFile? file) + { + if (file == null || file.Length == 0) return ""; + + using (var reader = new StreamReader(file.OpenReadStream())) + { + return reader.ReadToEnd(); + } + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/ModelBuilder.cs b/mohaymen-codestar-Team02/Services/ModelBuilder.cs new file mode 100644 index 0000000..4c984d6 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/ModelBuilder.cs @@ -0,0 +1,57 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace mohaymen_codestar_Team02.Services; + +public class ModelBuilder +{ + public Type CreateDynamicClass(string className, Dictionary fieldNamesTypes, Type interfaceType) + { + var typeBuilder = GetTypeBuilder(className); + + if (interfaceType != null) + { + typeBuilder.AddInterfaceImplementation(interfaceType); + } + + foreach (var fieldNamesType in fieldNamesTypes) + { + CreateProperty(typeBuilder, fieldNamesType.Key, fieldNamesType.Value); + } + + return typeBuilder.CreateType(); + } + + private TypeBuilder GetTypeBuilder(string className) + { + var typeSignature = className; + var assemblyName = new AssemblyName(typeSignature); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); + return moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class); + } + + private void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) + { + var fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); + + var propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); + var getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); + var getIl = getPropMthdBldr.GetILGenerator(); + + getIl.Emit(OpCodes.Ldarg_0); + getIl.Emit(OpCodes.Ldfld, fieldBuilder); + getIl.Emit(OpCodes.Ret); + + var setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); + var setIl = setPropMthdBldr.GetILGenerator(); + + setIl.Emit(OpCodes.Ldarg_0); + setIl.Emit(OpCodes.Ldarg_1); + setIl.Emit(OpCodes.Stfld, fieldBuilder); + setIl.Emit(OpCodes.Ret); + + propertyBuilder.SetGetMethod(getPropMthdBldr); + propertyBuilder.SetSetMethod(setPropMthdBldr); + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/ObjectBuilder.cs b/mohaymen-codestar-Team02/Services/ObjectBuilder.cs new file mode 100644 index 0000000..2beb875 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/ObjectBuilder.cs @@ -0,0 +1,34 @@ +using mohaymen_codestar_Team02.Data; + +namespace mohaymen_codestar_Team02.Services.TokenService; + +public class ObjectBuilder +{ + + public object CreateDynamicObject(Type objectType, Dictionary attributeValues) + { + var dynamicObject = Activator.CreateInstance(objectType); + + foreach (var attributeValue in attributeValues) + { + objectType.GetProperty(attributeValue.Key).SetValue(dynamicObject, attributeValue.Value); + } + + return dynamicObject; + } + + public object CreateDynamicObject1(Type objectType, Dictionary attributeValues, Type vertexType, object source, object destination) + { + var dynamicObject = Activator.CreateInstance(objectType); + + vertexType.GetProperty("Source").SetValue(vertexType, source); + vertexType.GetProperty("Target").SetValue(vertexType, destination); + + foreach (var attributeValue in attributeValues) + { + objectType.GetProperty(attributeValue.Key).SetValue(dynamicObject, attributeValue.Value); + } + + return dynamicObject; + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/PasswordHandller/PasswordService.cs b/mohaymen-codestar-Team02/Services/PasswordHandller/PasswordService.cs index b84a043..2dc412d 100644 --- a/mohaymen-codestar-Team02/Services/PasswordHandller/PasswordService.cs +++ b/mohaymen-codestar-Team02/Services/PasswordHandller/PasswordService.cs @@ -17,13 +17,9 @@ public bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] pass { var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); - for (int i = 0; i < computedHash.Length; i++) - { + for (var i = 0; i < computedHash.Length; i++) if (computedHash[i] != passwordHash[i]) - { return false; - } - } return true; } diff --git a/mohaymen-codestar-Team02/Services/ProfileService/ProfileService.cs b/mohaymen-codestar-Team02/Services/ProfileService/ProfileService.cs index 32ab9ea..0041bd7 100644 --- a/mohaymen-codestar-Team02/Services/ProfileService/ProfileService.cs +++ b/mohaymen-codestar-Team02/Services/ProfileService/ProfileService.cs @@ -44,7 +44,7 @@ public async Task> ChangePassword(string previousPasswor if (!_passwordService.VerifyPasswordHash(previousPassword, user.PasswordHash, user.Salt)) return new ServiceResponse(new { }, ApiResponseType.BadRequest, Resources.WrongPasswordMessage); - _passwordService.CreatePasswordHash(newPassword, out byte[] passwordHash, out byte[] passwordSalt); + _passwordService.CreatePasswordHash(newPassword, out var passwordHash, out var passwordSalt); user.PasswordHash = passwordHash; user.Salt = passwordSalt; diff --git a/mohaymen-codestar-Team02/Services/ShowGraphService/IShowGraphService.cs b/mohaymen-codestar-Team02/Services/ShowGraphService/IShowGraphService.cs new file mode 100644 index 0000000..f501584 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/ShowGraphService/IShowGraphService.cs @@ -0,0 +1,5 @@ +namespace mohaymen_codestar_Team02.Services.ShowGraphService; + +public interface IShowGraphService +{ +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IEdageStorer.cs b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IEdageStorer.cs new file mode 100644 index 0000000..d2077a1 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IEdageStorer.cs @@ -0,0 +1,5 @@ +namespace mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +public interface IEdageStorer : IStoreDataService +{ +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IStorHandler.cs b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IStorHandler.cs new file mode 100644 index 0000000..9fe8bea --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IStorHandler.cs @@ -0,0 +1,8 @@ +namespace mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +public interface IStorHandler +{ + public IEdageStorer EdageStorer { get; set; } + public IVertexStorer VertexStorer { get; set; } + Task StoreDataSet(string? nameData, string userId); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IStoreDataservice.cs b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IStoreDataservice.cs new file mode 100644 index 0000000..13c20d0 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IStoreDataservice.cs @@ -0,0 +1,8 @@ +using System.Dynamic; + +namespace mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +public interface IStoreDataService +{ + Task StoreFileData(string entityName, string dataFile, long dataGroupId); +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IVertexStorer.cs b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IVertexStorer.cs new file mode 100644 index 0000000..47e07b5 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/Abstraction/IVertexStorer.cs @@ -0,0 +1,5 @@ +namespace mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +public interface IVertexStorer : IStoreDataService +{ +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/EdgeStorerCsv.cs b/mohaymen-codestar-Team02/Services/StoreData/EdgeStorerCsv.cs new file mode 100644 index 0000000..3861653 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/EdgeStorerCsv.cs @@ -0,0 +1,60 @@ +using System.Dynamic; +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Models.EdgeEAV; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +namespace mohaymen_codestar_Team02.Services.StoreData; + +public class EdgeStorerCsv : IEdageStorer +{ + private readonly IServiceProvider? _serviceProvider; + public EdgeStorerCsv(IServiceProvider? serviceProvider) + { + _serviceProvider = serviceProvider; + } + public async Task StoreFileData(string entityName, string dataFile, long dataGroupId) + { + using var scope = _serviceProvider.CreateScope(); + var dataContext = scope.ServiceProvider.GetRequiredService(); + // try + // { + var edgeEntity = new EdgeEntity(entityName, dataGroupId); + List edgeAttributes = new(); + List edgeValues = new(); + await dataContext.EdgeEntities.AddAsync(edgeEntity); + await dataContext.SaveChangesAsync(); + using (var reader = new StringReader(dataFile)) + { + var headerLine = reader.ReadLine(); + if (headerLine == null) return false; + + var headers = headerLine.Split(','); + foreach (var att in headers) edgeAttributes.Add(new EdgeAttribute(att, edgeEntity.Id)); + + foreach (var attribute in edgeAttributes) await dataContext.EdgeAttributes.AddAsync(attribute); + + await dataContext.SaveChangesAsync(); + string? line; + while (!string.IsNullOrEmpty(line = reader.ReadLine())) + { + var objectId = Guid.NewGuid().ToString(); + var values = line.Split("\",\""); + values[0] = values[0].Substring(1); + var lastWord = values[values.Length - 1]; + values[values.Length - 1] = lastWord.Substring(0, lastWord.Length - 1); + for (var i = 0; i < values.Length; i++) + edgeValues.Add(new EdgeValue(values[i], edgeAttributes[i].Id, objectId)); + } + } + + foreach (var value in edgeValues) await dataContext.EdgeValues.AddAsync(value); + + await dataContext.SaveChangesAsync(); + return true; + // } + // catch (Exception e) + // { + // return false; + // } + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/StoreDataService.cs b/mohaymen-codestar-Team02/Services/StoreData/StoreDataService.cs new file mode 100644 index 0000000..a79dcd2 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/StoreDataService.cs @@ -0,0 +1,39 @@ +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Models; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +namespace mohaymen_codestar_Team02.Services.StoreData; + +public class StoreDataService + : IStorHandler +{ + private readonly IServiceProvider _serviceProvider; + + public StoreDataService(IServiceProvider serviceProvider, IEdageStorer edageStorer, IVertexStorer vertexStorer) + { + _serviceProvider = serviceProvider; + VertexStorer = vertexStorer; + EdageStorer = edageStorer; + } + public IEdageStorer EdageStorer { get; set; } + public IVertexStorer VertexStorer { get; set; } + + public async Task StoreDataSet(string? nameData, string userName) + { + using var scope = _serviceProvider.CreateScope(); + var context = scope.ServiceProvider.GetRequiredService(); + try + { + if (string.IsNullOrEmpty(nameData)) return -1; + var setData = new DataGroup(nameData, + context.Users.SingleOrDefault(u => u.Username.ToLower() == userName.ToLower()).UserId); + await context.DataSets.AddAsync(setData); + await context.SaveChangesAsync(); + return setData.DataGroupId; + } + catch (ArgumentException e) + { + return -1; + } + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/Services/StoreData/VertexStorerCsv.cs b/mohaymen-codestar-Team02/Services/StoreData/VertexStorerCsv.cs new file mode 100644 index 0000000..e841525 --- /dev/null +++ b/mohaymen-codestar-Team02/Services/StoreData/VertexStorerCsv.cs @@ -0,0 +1,72 @@ +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Models.EdgeEAV; +using mohaymen_codestar_Team02.Models.VertexEAV; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; + +namespace mohaymen_codestar_Team02.Services.StoreData; + +public class VertexStorerCsv : IVertexStorer +{ + private readonly IServiceProvider _serviceProvider; + public VertexStorerCsv(IServiceProvider serviceProvider) + { + this._serviceProvider = serviceProvider; + } + public async Task StoreFileData(string entityName, string dataFile, long dataGroupId) + { + using var scope = _serviceProvider.CreateScope(); + var dataContext = scope.ServiceProvider.GetRequiredService(); + try + { + var edgeEntity = new VertexEntity(entityName, dataGroupId); + List edgeAttributes = new(); + List edgeValues = new(); + await dataContext.VertexEntities.AddAsync(edgeEntity); + await dataContext.SaveChangesAsync(); + using (var reader = new StringReader(dataFile)) + { + var headerLine = reader.ReadLine(); + if (headerLine == null) return false; + + var headers = headerLine.Split("\",\""); + headers[0] = headers[0].Substring(1); + if (headers.Length != 0) + { + var lastWords = headers[headers.Length - 1]; + headers[headers.Length - 1] = lastWords.Substring(0, lastWords.Length - 1); + } + + foreach (var att in headers) edgeAttributes.Add(new VertexAttribute(att, edgeEntity.Id)); + + foreach (var attribute in edgeAttributes) await dataContext.VertexAttributes.AddAsync(attribute); + + await dataContext.SaveChangesAsync(); + string? line; + while (!string.IsNullOrEmpty(line = reader.ReadLine())) + { + var objectId = Guid.NewGuid().ToString(); + var values = line.Split("\",\""); + + values[0] = values[0].Substring(1); + if (values.Length != 0) + { + var lastWord = values[values.Length - 1]; + values[values.Length - 1] = lastWord.Substring(0, lastWord.Length - 1); + } + + for (var i = 0; i < values.Length; i++) + edgeValues.Add(new VertexValue(values[i], edgeAttributes[i].Id, objectId)); + } + } + + foreach (var value in edgeValues) await dataContext.VertexValues.AddAsync(value); + + await dataContext.SaveChangesAsync(); + return true; + } + catch (Exception e) + { + return false; + } + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02/appsettings.json b/mohaymen-codestar-Team02/appsettings.json index 66cac70..1c08b37 100644 --- a/mohaymen-codestar-Team02/appsettings.json +++ b/mohaymen-codestar-Team02/appsettings.json @@ -1,7 +1,4 @@ { - "ConnectionStrings": { - "DefaultConnection": "Host=localhost;Port=5432;Database=mohaymen_group02_project;Username=postgres;Password=ftmdkf413;" - }, "AppSettings": { "Token": "my top secret key is right here hehe jkjkjkj yguguygugyuguyguuygggyuguyuygu jhj" }, diff --git a/mohaymen-codestar-Team02/initialProgram/InitialApp.cs b/mohaymen-codestar-Team02/initialProgram/InitialApp.cs index 2c2bc6f..dbef849 100644 --- a/mohaymen-codestar-Team02/initialProgram/InitialApp.cs +++ b/mohaymen-codestar-Team02/initialProgram/InitialApp.cs @@ -7,19 +7,19 @@ public class InitialApp { public static void ConfigureApp(WebApplication app) { - // Apply pending migrations (uncomment if needed) - using (var scope = app.Services.CreateScope()) - { - var services = scope.ServiceProvider; - - var context = services.GetRequiredService(); - context.Database.EnsureCreated(); - - if (context.Database.GetPendingMigrations().Any()) - { - context.Database.Migrate(); - } - } + // // Apply pending migrations (uncomment if needed) + // using (var scope = app.Services.CreateScope()) + // { + // var services = scope.ServiceProvider; + // + // var context = services.GetRequiredService(); + // context.Database.EnsureCreated(); + // + // if (context.Database.GetPendingMigrations().Any()) + // { + // context.Database.Migrate(); + // } + // } // Initialize services using (var scope = app.Services.CreateScope()) diff --git a/mohaymen-codestar-Team02/initialProgram/InitialServices.cs b/mohaymen-codestar-Team02/initialProgram/InitialServices.cs index 756ee60..7c518f8 100644 --- a/mohaymen-codestar-Team02/initialProgram/InitialServices.cs +++ b/mohaymen-codestar-Team02/initialProgram/InitialServices.cs @@ -9,8 +9,12 @@ using mohaymen_codestar_Team02.Services.Administration; using mohaymen_codestar_Team02.Services.Authenticatoin; using mohaymen_codestar_Team02.Services.CookieService; +using mohaymen_codestar_Team02.Services.DataAdminService; +using mohaymen_codestar_Team02.Services.FileReaderService; using mohaymen_codestar_Team02.Services.PasswordHandller; using mohaymen_codestar_Team02.Services.ProfileService; +using mohaymen_codestar_Team02.Services.StoreData; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; using mohaymen_codestar_Team02.Services.TokenService; namespace mohaymen_codestar_Team02.initialProgram; @@ -34,8 +38,9 @@ public static void ConfigureServices(IServiceCollection services, WebApplication services.AddHttpContextAccessor(); // Configure DbContext and Dependency Injection + var cs = Environment.GetEnvironmentVariable("CONNECTION_STRING"); services.AddDbContext(options => - options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseNpgsql(cs)); services .AddScoped() @@ -44,7 +49,12 @@ public static void ConfigureServices(IServiceCollection services, WebApplication .AddScoped() .AddScoped() .AddScoped() - .AddScoped(); + .AddScoped() + .AddSingleton() + .AddSingleton() + .AddTransient() + .AddSingleton() + .AddSingleton(); services.AddAutoMapper(typeof(AutoMapperProfile)); services.AddAuthorization(); @@ -66,10 +76,7 @@ public static void ConfigureAuthentication(IServiceCollection services) OnMessageReceived = context => { var token = context.HttpContext.Request.Cookies["login"]; - if (!string.IsNullOrEmpty(token)) - { - context.Token = token; - } + if (!string.IsNullOrEmpty(token)) context.Token = token; return Task.CompletedTask; } @@ -90,19 +97,19 @@ public static void ConfigureAuthentication(IServiceCollection services) public void SeadRole() { - List roles = new List() + List roles = new() { - new Role() + new() { RoleId = 1, RoleType = "SystemAdmin" }, - new Role() + new() { RoleId = 2, RoleType = "Analyst" }, - new Role() + new() { RoleId = 3, RoleType = "DataAdmin" @@ -113,12 +120,10 @@ public void SeadRole() foreach (var role in roles) { if (!_context.Roles.Any(r => r.RoleType == role.RoleType)) - { _context.Roles.Add(role); - } - } - _context.SaveChanges(); + _context.SaveChanges(); + } } public void SeadAdmin() @@ -127,9 +132,9 @@ public void SeadAdmin() { var admin = new User() { - Username = "admin", + Username = "admin" }; - _passwordService.CreatePasswordHash("admin", out byte[] passwordHash, out byte[] passwordSalt); + _passwordService.CreatePasswordHash("admin", out var passwordHash, out var passwordSalt); admin.PasswordHash = passwordHash; admin.Salt = passwordSalt; diff --git a/mohaymen-codestar-Team02/mohaymen-codestar-Team02.csproj b/mohaymen-codestar-Team02/mohaymen-codestar-Team02.csproj index 41de41d..cdd2afc 100644 --- a/mohaymen-codestar-Team02/mohaymen-codestar-Team02.csproj +++ b/mohaymen-codestar-Team02/mohaymen-codestar-Team02.csproj @@ -20,6 +20,7 @@ + @@ -41,8 +42,4 @@ - - - - diff --git a/mohaymen-codestar-Team02_XUnitTest/Servies/Administration/AdminServiceTest.cs b/mohaymen-codestar-Team02_XUnitTest/Servies/Administration/AdminServiceTest.cs index f9b46dd..99665b3 100644 --- a/mohaymen-codestar-Team02_XUnitTest/Servies/Administration/AdminServiceTest.cs +++ b/mohaymen-codestar-Team02_XUnitTest/Servies/Administration/AdminServiceTest.cs @@ -32,7 +32,6 @@ public AdminServiceTest() .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) .Options; _mockContext = new DataContext(options); - _sut = new AdminService(_mockContext, _cookieService, _tokenService, _passwordService, _mapper); } diff --git a/mohaymen-codestar-Team02_XUnitTest/Servies/DataAdminService/DataAdminServiceTest.cs b/mohaymen-codestar-Team02_XUnitTest/Servies/DataAdminService/DataAdminServiceTest.cs new file mode 100644 index 0000000..d38f886 --- /dev/null +++ b/mohaymen-codestar-Team02_XUnitTest/Servies/DataAdminService/DataAdminServiceTest.cs @@ -0,0 +1,76 @@ +using mohaymen_codestar_Team02.Models; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; +using NSubstitute; + +namespace mohaymen_codestar_Team02_XUnitTest.Servies.DataAdminService; + +public class DataAdminServiceTest +{ + private readonly IStorHandler _storHandler; + private readonly mohaymen_codestar_Team02.Services.DataAdminService.DataAdminService _sut; + + public DataAdminServiceTest() + { + _storHandler = Substitute.For(); + _sut = new mohaymen_codestar_Team02.Services.DataAdminService.DataAdminService(_storHandler); + _storHandler.EdageStorer.StoreFileData(Arg.Any(), Arg.Any(), Arg.Any()).Returns(true); + _storHandler.VertexStorer.StoreFileData(Arg.Any(), Arg.Any(), Arg.Any()).Returns(true); + } + + [Theory] + [InlineData("")] + [InlineData(null)] + public async Task StoreData_ReturnsBadRequest_WhenNameIsNullOrEmpty(string? name) + { + //Arrange + //Action + var result = await _sut.StoreData("sample", "sample", "mahdddd", name, "ma", "8"); + //Assert + Assert.Equal(ApiResponseType.BadRequest, result.Type); + } + [Fact] + public async Task StoreData_ReturnsBadRequest_WhenCreatingTheDataGroupIsFail() + { + //Arrange + _storHandler.StoreDataSet("mahdddd", "8").Returns(-1); + //Action + var result = await _sut.StoreData("sample", "sample", "mahdddd", "name", "ma", "8"); + //Assert + Assert.Equal(ApiResponseType.BadRequest, result.Type); + } + + [Fact] + public async Task StoreData_ReturnsBadRequest_WhenEdageStorerStoreValuesReturnFalse() + { + //Arrange + _storHandler.EdageStorer.StoreFileData(Arg.Any(), Arg.Any(), Arg.Any()).Returns(false); + //Action + var result = await _sut.StoreData("sample", "sample", "test", "mahdddd", "mahdddd", "8"); + //Assert + Assert.Equal(ApiResponseType.BadRequest, result.Type); + } + + [Fact] + public async Task StoreData_ReturnsBadRequest_WhenVertexStorerStoreValuesReturnFalse() + { + // Arrange + _storHandler.VertexStorer.StoreFileData(Arg.Any(), Arg.Any(), Arg.Any()).Returns(false); + + // Act + var result = await _sut.StoreData("sampleEdgeFile", "sampleVertexFile", "testData", "mamama", "mmm", "2"); + + // Assert + Assert.Equal(ApiResponseType.BadRequest, result.Type); + } + + [Fact] + public async Task StoreData_ReturnsSuccess_WhenInputAreValid() + { + // Arrange + _storHandler.StoreDataSet(Arg.Any(), Arg.Any()).Returns(9); + // Act + var result = await _sut.StoreData("sampleEdgeFile", "sampleVertexFile", "testData", "a", "lll", "2"); + // Assert + Assert.Equal(ApiResponseType.Success, result.Type); + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/EdgeStorerCsvTest.cs b/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/EdgeStorerCsvTest.cs new file mode 100644 index 0000000..5a2554f --- /dev/null +++ b/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/EdgeStorerCsvTest.cs @@ -0,0 +1,74 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Models.EdgeEAV; +using mohaymen_codestar_Team02.Services.StoreData; +using NSubstitute; + +namespace mohaymen_codestar_Team02_XUnitTest.Servies.StorData +{ + public class EdgeStorerCsvTests + { + private EdgeStorerCsv _sut; + private DataContext _dataContext; + private ServiceProvider _serviceProvider; + + public EdgeStorerCsvTests() + { + var serviceCollection = new ServiceCollection(); + + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) + .Options; + + serviceCollection.AddScoped(_ => new DataContext(options)); + + _serviceProvider = serviceCollection.BuildServiceProvider(); + + _sut = new(_serviceProvider); + using var scope = _serviceProvider.CreateScope(); + _dataContext = scope.ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task StoreFileData_ShouldReturnTrue_WhenDataIsValid() + { + using var scope = _serviceProvider.CreateScope(); + _dataContext = scope.ServiceProvider.GetRequiredService(); + + // Arrange + string entityName = "TestEntity"; + string dataFile = "attribute1,attribute2\nvalue1,value2\nlol1,lol2"; + var dataGroupId = 1; + + // Act + var result = await _sut.StoreFileData(entityName, dataFile, dataGroupId); + + // Assert + Assert.True(result); + Assert.Equal(1, await _dataContext.EdgeEntities.CountAsync()); + Assert.Equal(2, await _dataContext.EdgeAttributes.CountAsync()); + Assert.Equal(2, await _dataContext.EdgeValues.CountAsync()); + } + + [Fact] + public async Task StoreFileData_ShouldReturnFalse_WhenHeaderLineIsNull() + { + using var scope = _serviceProvider.CreateScope(); + _dataContext = scope.ServiceProvider.GetRequiredService(); + // Arrange + string entityName = "TestEntity"; + string dataFile = ""; // No headers in the file + var dataGroupId = 1; + + // Act + var result = await _sut.StoreFileData(entityName, dataFile, dataGroupId); + + // Assert + Assert.False(result); + Assert.Equal(1, await _dataContext.EdgeEntities.CountAsync()); + Assert.Equal(0, await _dataContext.EdgeAttributes.CountAsync()); + Assert.Equal(0, await _dataContext.EdgeValues.CountAsync()); + } + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/StoreDataServiceTest.cs b/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/StoreDataServiceTest.cs new file mode 100644 index 0000000..e1845e2 --- /dev/null +++ b/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/StoreDataServiceTest.cs @@ -0,0 +1,63 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Models; +using mohaymen_codestar_Team02.Services.StoreData; +using mohaymen_codestar_Team02.Services.StoreData.Abstraction; +using NSubstitute; + +namespace mohaymen_codestar_Team02_XUnitTest.Servies.StorData; + +public class StoreDataServiceTest +{ + private StoreDataService _sut; + private ServiceProvider _serviceProvider; + + public StoreDataServiceTest() + { + var serviceCollection = new ServiceCollection(); + + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) + .Options; + + serviceCollection.AddScoped(_ => new DataContext(options)); + + _serviceProvider = serviceCollection.BuildServiceProvider(); + IEdageStorer edageStorer = Substitute.For(); + IVertexStorer vertexStorer = Substitute.For(); + _sut = new StoreDataService(_serviceProvider, edageStorer, vertexStorer); + + } + + [Fact] + public async Task StoreDataSet_ShouldStoreTheData_whenDataIsVilid() + { + using var scope = _serviceProvider.CreateScope(); + var mockContext = scope.ServiceProvider.GetRequiredService(); + //Arrange + var name = "mahdi"; + mockContext.Users.Add(new User() + { Username = "3", UserId = 4, PasswordHash = Array.Empty(), Salt = Array.Empty() }); + mockContext.SaveChanges(); + //Act + var bolResult = await _sut.StoreDataSet(name, "3"); + var result = await mockContext.DataSets.FirstOrDefaultAsync(x => x.Name == name); + //Assert + Assert.True(bolResult != -1); + Assert.Equal(result?.Name, name); + } + + [Fact] + public async Task StoreDataSet_ShouldReturnFalse_NameDataIsNull() + { + using var scope = _serviceProvider.CreateScope(); + var mockContext = scope.ServiceProvider.GetRequiredService(); + //Arrange + //Act + var result = await _sut.StoreDataSet(null, "3"); + //Assert + Assert.True(result == -1); + Assert.Empty(mockContext.DataSets); + } +} \ No newline at end of file diff --git a/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/VertexStorerCsvTest.cs b/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/VertexStorerCsvTest.cs new file mode 100644 index 0000000..606e9d5 --- /dev/null +++ b/mohaymen-codestar-Team02_XUnitTest/Servies/StorData/VertexStorerCsvTest.cs @@ -0,0 +1,74 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using mohaymen_codestar_Team02.Data; +using mohaymen_codestar_Team02.Services.StoreData; + +namespace mohaymen_codestar_Team02_XUnitTest.Servies.StorData +{ + public class VertexStorerCsvTests + { + private VertexStorerCsv _sut; + private DataContext _dataContext; + private ServiceProvider _serviceProvider; + + public VertexStorerCsvTests() + { + var serviceCollection = new ServiceCollection(); + + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) + .Options; + + serviceCollection.AddScoped(_ => new DataContext(options)); + + _serviceProvider = serviceCollection.BuildServiceProvider(); + + _sut = new(_serviceProvider); + using var scope = _serviceProvider.CreateScope(); + _dataContext = scope.ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task StoreFileData_ShouldReturnTrue_WhenDataIsValid() + { + using var scope = _serviceProvider.CreateScope(); + _dataContext = scope.ServiceProvider.GetRequiredService(); + + // Arrange + string entityName = "TestEntity"; + string dataFile = "attribute1,attribute2\nvalue1,value2\nlol1,lol2"; + var dataGroupId = 1; + + + // Act + var result = await _sut.StoreFileData(entityName, dataFile, dataGroupId); + + // Assert + Assert.True(result); + Assert.Equal(1, await _dataContext.VertexEntities.CountAsync()); + Assert.Equal(1, await _dataContext.VertexAttributes.CountAsync()); + Assert.Equal(2, await _dataContext.VertexValues.CountAsync()); + } + + [Fact] + public async Task StoreFileData_ShouldReturnFalse_WhenHeaderLineIsNull() + { + using var scope = _serviceProvider.CreateScope(); + _dataContext = scope.ServiceProvider.GetRequiredService(); + + // Arrange + string entityName = "TestEntity"; + string dataFile = ""; + var dataGroupId = 1; + + // Act + var result = await _sut.StoreFileData(entityName, dataFile, dataGroupId); + + // Assert + Assert.False(result); + Assert.Equal(1, await _dataContext.VertexEntities.CountAsync()); + Assert.Equal(0, await _dataContext.VertexAttributes.CountAsync()); + Assert.Equal(0, await _dataContext.VertexValues.CountAsync()); + } + } +} \ No newline at end of file