Skip to content

Commit 1ca7df2

Browse files
authored
Merge pull request #74 from boolean-uk/81-api-create-exerciseendpoints
Create endpoints for Exercise
2 parents ec0b8b6 + ac93467 commit 1ca7df2

File tree

4 files changed

+290
-1
lines changed

4 files changed

+290
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using exercise.wwwapi.Models;
2+
3+
namespace exercise.wwwapi.DTOs.Exercises
4+
{
5+
public class UpdateCreateExerciseDTO
6+
{
7+
public string Name { get; set; }
8+
public string GitHubLink { get; set; }
9+
public string Description { get; set; }
10+
11+
}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace exercise.wwwapi.DTOs.Exercises
2+
{
3+
public class UpdateWithNewUnitExerciseDTO
4+
{
5+
public string Name { get; set; }
6+
public string GitHubLink { get; set; }
7+
public string Description { get; set; }
8+
public int UnitId { get; set; }
9+
10+
}
11+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace exercise.wwwapi.DTOs
2+
{
3+
public class GetUserProfileDTO
4+
{
5+
}
6+
}

exercise.wwwapi/Endpoints/ExerciseEndpoints.cs

Lines changed: 261 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,24 @@ public static void ConfigureExerciseEndpoints(this WebApplication app)
3434
var exercises = app.MapGroup("exercises");
3535
exercises.MapGet("/", GetExercises).WithSummary("Returns all exercises");
3636
exercises.MapGet("/{id}", GetExerciseById).WithSummary("Returns exercise with provided id");
37+
exercises.MapDelete("/{id}", DeleteExerciseById).WithSummary("Deletes exercise with provided id");
38+
exercises.MapPut("/{id}", UpdateExerciseById).WithSummary("Update exercise with provided id");
3739

3840
var units = app.MapGroup("units");
3941
units.MapGet("/", GetUnits).WithSummary("Returns all units");
4042
units.MapGet("/{id}", GetUnitById).WithSummary("Returns unit with provided id");
43+
units.MapPost("/{id}", CreateExerciseInUnit).WithSummary("Create an exercise in the given unit");
44+
units.MapDelete("/{id}", DeleteUnit).WithSummary("Deletes unit with provided id");
45+
units.MapPut("/{id}", UpdateUnit).WithSummary("Update unit with provided id");
4146

4247
var modules = app.MapGroup("modules");
4348
modules.MapGet("/", GetModules).WithSummary("Returns all modules");
4449
modules.MapGet("/{id}", GetModuleById).WithSummary("Returns module with provided id");
50+
modules.MapPost("/", CreateModule).WithSummary("Create a new module");
51+
modules.MapPut("/{id}", UpdateModule).WithSummary("Update a module with provided id");
52+
modules.MapDelete("/{id}", DeleteModule).WithSummary("Delete a module with provided id");
53+
modules.MapPost("/{id}", CreateUnitInModule).WithSummary("Create a unit in the given module");
54+
//TODO: Add MapPost to modules which creates a new Unit in the module
4555

4656

4757
}
@@ -54,14 +64,115 @@ private static async Task<IResult> GetModules(IRepository<Module> moduleReposito
5464
return TypedResults.Ok(result);
5565
}
5666

67+
[ProducesResponseType(StatusCodes.Status404NotFound)]
5768
[ProducesResponseType(StatusCodes.Status200OK)]
5869
private static async Task<IResult> GetModuleById(IRepository<Module> moduleRepository, int id)
5970
{
6071
var response = await moduleRepository.GetByIdWithIncludes(a => a.Include(u => u.Units).ThenInclude(u => u.Exercises), id);
72+
if (response == null)
73+
{
74+
return TypedResults.NotFound();
75+
}
76+
77+
var result = new GetModuleDTO(response);
78+
return TypedResults.Ok(result);
79+
}
80+
81+
[ProducesResponseType(StatusCodes.Status200OK)]
82+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
83+
private static async Task<IResult> CreateModule(IRepository<Module> moduleRepository, ClaimsPrincipal claimsPrincipal, string moduleTitle)
84+
{
85+
var authorized = claimsPrincipal.IsInRole("Teacher");
86+
if (!authorized)
87+
{
88+
return TypedResults.Unauthorized();
89+
}
90+
91+
var newModule = new Module { Title = moduleTitle };
92+
93+
moduleRepository.Insert(newModule);
94+
await moduleRepository.SaveAsync();
95+
96+
var result = new GetModuleDTO(newModule);
97+
return TypedResults.Ok(result);
98+
}
99+
100+
[ProducesResponseType(StatusCodes.Status200OK)]
101+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
102+
[ProducesResponseType(StatusCodes.Status404NotFound)]
103+
private static async Task<IResult> UpdateModule(IRepository<Module> moduleRepository, ClaimsPrincipal claimsPrincipal, int id, string moduleTitle)
104+
{
105+
var authorized = claimsPrincipal.IsInRole("Teacher");
106+
if (!authorized)
107+
{
108+
return TypedResults.Unauthorized();
109+
}
110+
111+
var response = await moduleRepository.GetByIdWithIncludes(a => a.Include(u => u.Units).ThenInclude(u => u.Exercises), id);
112+
if (response == null)
113+
{
114+
return TypedResults.NotFound();
115+
}
116+
117+
response.Title = moduleTitle;
118+
moduleRepository.Update(response);
119+
await moduleRepository.SaveAsync();
120+
121+
var result = new GetModuleDTO(response);
122+
return TypedResults.Ok(result);
123+
}
124+
// TODO: Create a DTO to make it easier to later change what module might hold/need when creating/editing a module
125+
126+
[ProducesResponseType(StatusCodes.Status200OK)]
127+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
128+
[ProducesResponseType(StatusCodes.Status404NotFound)]
129+
private static async Task<IResult> DeleteModule(IRepository<Module> moduleRepository, ClaimsPrincipal claimsPrincipal, int id)
130+
{
131+
var authorized = claimsPrincipal.IsInRole("Teacher");
132+
if (!authorized)
133+
{
134+
return TypedResults.Unauthorized();
135+
}
136+
137+
var response = await moduleRepository.GetByIdWithIncludes(a => a.Include(u => u.Units).ThenInclude(u => u.Exercises), id);
138+
if (response == null)
139+
{
140+
return TypedResults.NotFound();
141+
}
142+
143+
moduleRepository.Delete(response);
144+
await moduleRepository.SaveAsync();
145+
61146
var result = new GetModuleDTO(response);
62147
return TypedResults.Ok(result);
63148
}
64149

150+
[ProducesResponseType(StatusCodes.Status200OK)]
151+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
152+
[ProducesResponseType(StatusCodes.Status404NotFound)]
153+
private static async Task<IResult> CreateUnitInModule(IRepository<Module> moduleRepository, IRepository<Unit> unitRepository, ClaimsPrincipal claimsPrincipal,int id, string name)
154+
{
155+
var authorized = claimsPrincipal.IsInRole("Teacher");
156+
if (!authorized)
157+
{
158+
return TypedResults.Unauthorized();
159+
}
160+
161+
var module = await moduleRepository.GetByIdWithIncludes(a => a.Include(u => u.Units).ThenInclude(u => u.Exercises), id);
162+
if (module == null)
163+
{
164+
return TypedResults.NotFound();
165+
}
166+
167+
var newUnit = new Unit { ModuleId = id, Name = name };
168+
169+
unitRepository.Insert(newUnit);
170+
await unitRepository.SaveAsync();
171+
172+
var result = new GetUnitDTO(newUnit);
173+
return TypedResults.Ok(result);
174+
}
175+
65176
[ProducesResponseType(StatusCodes.Status200OK)]
66177
private static async Task<IResult> GetUnits(IRepository<Unit> unitRepository, ClaimsPrincipal claimsPrincipal)
67178
{
@@ -70,14 +181,96 @@ private static async Task<IResult> GetUnits(IRepository<Unit> unitRepository, Cl
70181
return TypedResults.Ok(result);
71182
}
72183

184+
[ProducesResponseType(StatusCodes.Status404NotFound)]
73185
[ProducesResponseType(StatusCodes.Status200OK)]
74186
private static async Task<IResult> GetUnitById(IRepository<Unit> unitRepository, int id)
75187
{
76188
var response = await unitRepository.GetByIdWithIncludes(a => a.Include(u => u.Exercises), id);
189+
if (response == null)
190+
{
191+
return TypedResults.NotFound();
192+
}
77193
var result = new GetUnitDTO(response);
78194
return TypedResults.Ok(result);
79195
}
80196

197+
[ProducesResponseType(StatusCodes.Status200OK)]
198+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
199+
[ProducesResponseType(StatusCodes.Status404NotFound)]
200+
private static async Task<IResult> DeleteUnit(IRepository<Unit> unitRepository, ClaimsPrincipal claimsPrincipal, int id)
201+
{
202+
var authorized = claimsPrincipal.IsInRole("Teacher");
203+
if (!authorized)
204+
{
205+
return TypedResults.Unauthorized();
206+
}
207+
208+
var response = await unitRepository.GetByIdWithIncludes(a => a.Include(u => u.Exercises), id);
209+
if (response == null)
210+
{
211+
return TypedResults.NotFound();
212+
}
213+
214+
unitRepository.Delete(response);
215+
await unitRepository.SaveAsync();
216+
217+
var result = new GetUnitDTO(response);
218+
return TypedResults.Ok(result);
219+
}
220+
221+
[ProducesResponseType(StatusCodes.Status200OK)]
222+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
223+
[ProducesResponseType(StatusCodes.Status404NotFound)]
224+
private static async Task<IResult> UpdateUnit(IRepository<Unit> unitRepository, ClaimsPrincipal claimsPrincipal,int id, string name)
225+
{
226+
var authorized = claimsPrincipal.IsInRole("Teacher");
227+
if (!authorized)
228+
{
229+
return TypedResults.Unauthorized();
230+
}
231+
232+
var response = await unitRepository.GetByIdWithIncludes(a => a.Include(u => u.Exercises), id);
233+
if (response == null)
234+
{
235+
return TypedResults.NotFound();
236+
}
237+
response.Name = name;
238+
unitRepository.Update(response);
239+
await unitRepository.SaveAsync();
240+
241+
var result = new GetUnitDTO(response);
242+
return TypedResults.Ok(result);
243+
}
244+
245+
[ProducesResponseType(StatusCodes.Status200OK)]
246+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
247+
[ProducesResponseType(StatusCodes.Status404NotFound)]
248+
private static async Task<IResult> CreateExerciseInUnit(
249+
IRepository<Exercise> exerciseRepository,
250+
IRepository<Unit> unitRepository,
251+
ClaimsPrincipal claimsPrincipal,
252+
int id,
253+
UpdateCreateExerciseDTO exerciseDTO)
254+
{
255+
var authorized = claimsPrincipal.IsInRole("Teacher");
256+
if (!authorized)
257+
{
258+
return TypedResults.Unauthorized();
259+
}
260+
261+
var unit = await unitRepository.GetByIdWithIncludes(null, id);
262+
if (unit == null)
263+
{
264+
return TypedResults.NotFound();
265+
}
266+
267+
var newExercise = new Exercise { UnitId = id, Name = exerciseDTO.Name, GitHubLink = exerciseDTO.GitHubLink, Description = exerciseDTO.Description };
268+
exerciseRepository.Insert(newExercise);
269+
await exerciseRepository.SaveAsync();
270+
271+
var result = new Exercise_noUnit(newExercise);
272+
return TypedResults.Ok(result);
273+
}
81274

82275
[ProducesResponseType(StatusCodes.Status200OK)]
83276
private static async Task<IResult> GetExercises(IRepository<Exercise> exerciseRepository, ClaimsPrincipal claimsPrincipal)
@@ -86,10 +279,77 @@ private static async Task<IResult> GetExercises(IRepository<Exercise> exerciseRe
86279
var result = response.Select(e => new Exercise_noUnit(e));
87280
return TypedResults.Ok(result);
88281
}
282+
89283
[ProducesResponseType(StatusCodes.Status200OK)]
284+
[ProducesResponseType(StatusCodes.Status404NotFound)]
90285
private static async Task<IResult> GetExerciseById(IRepository<Exercise> exerciseRepository, int id)
91286
{
92287
var response = await exerciseRepository.GetByIdWithIncludes(null, id);
93-
return TypedResults.Ok(response);
288+
if (response == null)
289+
{
290+
return TypedResults.NotFound();
291+
}
292+
var result = new Exercise_noUnit(response);
293+
return TypedResults.Ok(result);
94294
}
295+
296+
[ProducesResponseType(StatusCodes.Status200OK)]
297+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
298+
[ProducesResponseType(StatusCodes.Status404NotFound)]
299+
private static async Task<IResult> DeleteExerciseById(IRepository<Exercise> exerciseRepository, ClaimsPrincipal claimsPrincipal, int id)
300+
{
301+
var authorized = claimsPrincipal.IsInRole("Teacher");
302+
if (!authorized)
303+
{
304+
return TypedResults.Unauthorized();
305+
}
306+
307+
var response = await exerciseRepository.GetByIdWithIncludes(null, id);
308+
if (response == null)
309+
{
310+
return TypedResults.NotFound();
311+
}
312+
313+
exerciseRepository.Delete(response);
314+
await exerciseRepository.SaveAsync();
315+
316+
var result = new Exercise_noUnit(response);
317+
return TypedResults.Ok(result);
318+
}
319+
320+
[ProducesResponseType(StatusCodes.Status200OK)]
321+
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
322+
[ProducesResponseType(StatusCodes.Status404NotFound)]
323+
private static async Task<IResult> UpdateExerciseById(IRepository<Exercise> exerciseRepository, IRepository<Unit> unitRepository, ClaimsPrincipal claimsPrincipal, int id, UpdateWithNewUnitExerciseDTO exerciseDTO)
324+
{
325+
var authorized = claimsPrincipal.IsInRole("Teacher");
326+
if (!authorized)
327+
{
328+
return TypedResults.Unauthorized();
329+
}
330+
331+
var unit = await unitRepository.GetByIdWithIncludes(null, exerciseDTO.UnitId);
332+
if ( unit == null)
333+
{
334+
return TypedResults.NotFound("Couldn't fint Unit");
335+
}
336+
var response = await exerciseRepository.GetByIdWithIncludes(null, id);
337+
if (response == null)
338+
{
339+
return TypedResults.NotFound();
340+
}
341+
342+
response.Name = exerciseDTO.Name;
343+
response.Description = exerciseDTO.Description;
344+
response.GitHubLink = exerciseDTO.GitHubLink;
345+
response.UnitId = exerciseDTO.UnitId;
346+
347+
exerciseRepository.Update(response);
348+
await exerciseRepository.SaveAsync();
349+
350+
var result = new Exercise_noUnit(response);
351+
return TypedResults.Ok(result);
352+
353+
}
354+
95355
}

0 commit comments

Comments
 (0)