Skip to content

Commit a82ea05

Browse files
authored
Merge pull request #101 from boolean-uk/91-backend---implement-cohort-structure
91 backend implement cohort structure
2 parents be646ed + 96d9324 commit a82ea05

File tree

18 files changed

+602
-50
lines changed

18 files changed

+602
-50
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using exercise.tests.Helpers;
2+
using Microsoft.AspNetCore.Mvc.Testing;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Net;
7+
using System.Text;
8+
using System.Text.Json.Nodes;
9+
using System.Threading.Tasks;
10+
11+
namespace exercise.tests.IntegrationTests
12+
{
13+
internal class CohortTests
14+
{
15+
private WebApplicationFactory<Program> _factory;
16+
private HttpClient _client;
17+
18+
[SetUp]
19+
public void SetUp()
20+
{
21+
// Arrange
22+
_factory = new WebApplicationFactory<Program>();
23+
_client = _factory.CreateClient();
24+
}
25+
26+
[TearDown]
27+
public void TearDown()
28+
{
29+
_client.Dispose();
30+
_factory.Dispose();
31+
}
32+
33+
[Test]
34+
public async Task GetAllCohorts()
35+
{
36+
var response = await _client.GetAsync("/cohorts");
37+
var contentString = await response.Content.ReadAsStringAsync();
38+
var message = string.IsNullOrWhiteSpace(contentString) ? null : JsonNode.Parse(contentString);
39+
40+
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
41+
Assert.That(message, Is.Not.Null);
42+
//Assert.That(message?["message"]?.GetValue<string>(), Is.EqualTo("success"));
43+
44+
var data = message?["data"]?.AsArray();
45+
Assert.That(data, Is.Not.Null);
46+
Assert.That(data!.Count, Is.GreaterThan(0));
47+
48+
var cohort = data!.First();
49+
Assert.That(cohort["id"]?.GetValue<int>(), Is.GreaterThan(0));
50+
Assert.That(cohort["title"].GetValue<string>, Is.Not.Null);
51+
//Assert.That(cohort["courses"]["students"].GetValue<Array>, Is.Not.Null);
52+
}
53+
}
54+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using exercise.wwwapi.DTOs.GetUsers;
2+
using exercise.wwwapi.Models;
3+
using System.ComponentModel.DataAnnotations.Schema;
4+
5+
namespace exercise.wwwapi.DTOs.Cohort
6+
{
7+
public class CohortCourseUserDTO
8+
{
9+
public string Cohort { get; set; }
10+
public string Course { get; set; }
11+
public UserBasicDTO User { get; set; }
12+
}
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using exercise.wwwapi.DTOs.GetUsers;
2+
3+
namespace exercise.wwwapi.DTOs.Cohort
4+
{
5+
public class CohortDTO
6+
{
7+
public int Id { get; set; }
8+
public string Title { get; set; }
9+
public ICollection<CourseInCohortDTO> Courses { get; set; } = new List<CourseInCohortDTO>();
10+
}
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using exercise.wwwapi.DTOs.GetUsers;
2+
3+
namespace exercise.wwwapi.DTOs.Cohort
4+
{
5+
public class CourseInCohortDTO
6+
{
7+
public string Title { get; set; }
8+
public ICollection<UserBasicDTO> Students { get; set; } = new List<UserBasicDTO>();
9+
public ICollection<UserBasicDTO> Teachers { get; set; } = new List<UserBasicDTO>();
10+
//public ICollection<UserCohortDTO> Students { get; set; } = new List<UserCohortDTO>();
11+
//public ICollection<UserCohortDTO> Teachers { get; set; } = new List<UserCohortDTO>();
12+
}
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace exercise.wwwapi.DTOs.Cohort
2+
{
3+
public class CreateCohortDTO
4+
{
5+
public required string Title { get; set; }
6+
}
7+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using exercise.wwwapi.Models;
2+
3+
namespace exercise.wwwapi.Data
4+
{
5+
public class CohortCourseData
6+
{
7+
private List<string> _courseNames = new List<string>()
8+
{
9+
"Software Development",
10+
"Front-End Development",
11+
"Data Analytics"
12+
};
13+
private List<string> _cohortNames = new List<string>()
14+
{
15+
"Cohort 1",
16+
"Cohort 2",
17+
"Best Cohort (Nigel's Cohort)",
18+
"Cohort 4",
19+
"Cohort 5",
20+
};
21+
private List<Course> _courses = new List<Course>();
22+
private List<Cohort> _cohorts = new List<Cohort>();
23+
private List<CohortCourse> _cohortCourses = new List<CohortCourse>();
24+
private List<CohortCourseUser> _cohortCourseUsers = new List<CohortCourseUser>();
25+
public CohortCourseData(List<User> users)
26+
{
27+
Random random = new Random(1);
28+
29+
for (int x = 0; x < _courseNames.Count; x++)
30+
{
31+
Course course = new Course() { Id = x+1 , Title = _courseNames[x] };
32+
_courses.Add(course);
33+
}
34+
35+
for (int x = 0; x < _cohortNames.Count; x++)
36+
{
37+
Cohort cohort = new Cohort() { Id = x+1 , Title = _cohortNames[x] };
38+
_cohorts.Add(cohort);
39+
}
40+
41+
foreach (var cohort in _cohorts)
42+
{
43+
foreach (var course in _courses)
44+
{
45+
CohortCourse cc = new CohortCourse()
46+
{
47+
CohortId = cohort.Id,
48+
CourseId = course.Id
49+
};
50+
_cohortCourses.Add(cc);
51+
}
52+
}
53+
54+
foreach (var user in users)
55+
{
56+
var cc = _cohortCourses[random.Next(_cohortCourses.Count)];
57+
CohortCourseUser ccu = new CohortCourseUser()
58+
{
59+
CohortId = cc.CohortId,
60+
CourseId = cc.CourseId,
61+
UserId = user.Id
62+
};
63+
_cohortCourseUsers.Add(ccu);
64+
}
65+
}
66+
public List<Course> Courses { get { return _courses; } }
67+
public List<Cohort> Cohorts { get { return _cohorts; } }
68+
public List<CohortCourse> CohortCourses { get { return _cohortCourses; } }
69+
public List<CohortCourseUser> CohortCourseUsers { get { return _cohortCourseUsers; } }
70+
71+
}
72+
}

exercise.wwwapi/Data/DataContext.cs

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,73 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
1717

1818
protected override void OnModelCreating(ModelBuilder modelBuilder)
1919
{
20-
21-
22-
modelBuilder.Entity<UserCohort>()
23-
.HasKey(uc => new { uc.UserId, uc.CohortId });
24-
20+
#region CohortCourse
21+
// Composite key for CohortCourse
22+
modelBuilder.Entity<CohortCourse>()
23+
.HasKey(cc => new { cc.CohortId, cc.CourseId });
24+
25+
modelBuilder.Entity<CohortCourseUser>()
26+
.HasKey(ccu => new { ccu.CohortId, ccu.CourseId, ccu.UserId });
27+
28+
// Relationships
29+
modelBuilder.Entity<CohortCourse>()
30+
.HasOne(cc => cc.Cohort)
31+
.WithMany(c => c.CohortCourses)
32+
.HasForeignKey(cc => cc.CohortId);
33+
34+
modelBuilder.Entity<CohortCourse>()
35+
.HasOne(cc => cc.Course)
36+
.WithMany(c => c.CohortCourses)
37+
.HasForeignKey(cc => cc.CourseId);
38+
39+
modelBuilder.Entity<CohortCourseUser>()
40+
.HasOne(ccu => ccu.Cohort)
41+
.WithMany() // ← Specify the inverse navigation
42+
.HasForeignKey(ccu => ccu.CohortId);
43+
44+
modelBuilder.Entity<CohortCourseUser>()
45+
.HasOne(ccu => ccu.Course)
46+
.WithMany() // ← Specify the inverse navigation
47+
.HasForeignKey(ccu => ccu.CourseId);
48+
49+
modelBuilder.Entity<CohortCourseUser>()
50+
.HasOne(ccu => ccu.User)
51+
.WithMany(u => u.CohortCourseUsers) // ← Specify the inverse navigation
52+
.HasForeignKey(ccu => ccu.UserId);
53+
#endregion CohortCourse
2554

2655
modelBuilder.Entity<User>()
2756
.Property(u => u.Role)
2857
.HasConversion<string>();
2958

30-
31-
//modelBuilder.Entity<User>()
32-
// .HasMany(u => u.Post)
33-
// .WithOne(p => p.User)
34-
// .HasForeignKey(p => p.UserId)
35-
// .OnDelete(DeleteBehavior.Cascade);
36-
3759
modelBuilder.Entity<Post>()
3860
.HasMany(p => p.Comments)
3961
.WithOne(c => c.Post)
4062
.HasForeignKey(c => c.PostId)
4163
.OnDelete(DeleteBehavior.Cascade);
4264

43-
//modelBuilder.Entity<UserCohort>()
44-
// .HasKey(tc => new { tc.UserId, tc.CohortId });
45-
46-
//modelBuilder.Entity<UserCohort>()
47-
// .HasOne(tc => tc.User)
48-
// .WithMany(u => u.TeacherCohorts)
49-
// .HasForeignKey(tc => tc.UserId);
50-
51-
//modelBuilder.Entity<UserCohort>()
52-
// .HasOne(tc => tc.Cohort)
53-
// .WithMany(c => c.TeacherCohorts)
54-
// .HasForeignKey(tc => tc.CohortId);
55-
5665
// seed users
5766
PersonData personData = new PersonData();
67+
// seed cohorts with courses
68+
CohortCourseData cohortCourseData = new CohortCourseData(personData.Users);
69+
// seed posts
5870
PostData postData = new PostData(personData.Users);
5971
PostCommentData postCommentData = new PostCommentData(postData.Posts, personData.Users);
6072
modelBuilder.Entity<User>().HasData(personData.Users);
6173
modelBuilder.Entity<Post>().HasData(postData.Posts);
6274
modelBuilder.Entity<PostComment>().HasData(postCommentData.Comments);
75+
modelBuilder.Entity<Course>().HasData(cohortCourseData.Courses);
76+
modelBuilder.Entity<Cohort>().HasData(cohortCourseData.Cohorts);
77+
modelBuilder.Entity<CohortCourse>().HasData(cohortCourseData.CohortCourses);
78+
modelBuilder.Entity<CohortCourseUser>().HasData(cohortCourseData.CohortCourseUsers);
6379

6480
}
6581
public DbSet<User> Users { get; set; }
6682
public DbSet<Post> Posts { get; set; }
6783
public DbSet<PostComment> PostComments { get; set; }
6884
public DbSet<Cohort> Cohorts { get; set; }
69-
public DbSet<UserCohort> UserCohorts { get; set; }
85+
public DbSet<Course> Courses { get; set; }
86+
public DbSet<CohortCourse> CohortCourses { get; set; }
87+
public DbSet<CohortCourseUser> CohortCourseUsers { get; set; }
7088
}
7189
}

0 commit comments

Comments
 (0)