chore: documentation and formatting for random quote and deleting categories

This commit is contained in:
2025-07-21 13:27:11 +02:00
parent d502e9d120
commit b96c780533
3 changed files with 88 additions and 94 deletions

View File

@@ -1,5 +1,5 @@
[*] [*]
end_of_line = crlf end_of_line = lf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true

View File

@@ -108,48 +108,55 @@ public class CategoryController : ControllerBase
// And send back to the user as DTO // And send back to the user as DTO
return Ok(cat.ToCategoryShortDTO()); return Ok(cat.ToCategoryShortDTO());
} }
[HttpDelete("{id}")] // DELETE /api/v1/categories
[Authorize] /// <summary>
[EnableCors] /// [AUTHED] Delete a category
[ProducesResponseType(200)] /// </summary>
[ProducesResponseType(typeof(ErrorDTO), 404)] /// <remarks>
public async Task<IActionResult> DeleteCategory(int id) /// Allows authorized users to delete categories.
{ /// <br/><br/>
// (Attempt to) find the quote /// Has CORS set.
Category? cat = await _db.Categories /// </remarks>
.FirstOrDefaultAsync(c => c.Id == id); /// <param name="id">Id of the category which shall be deleted</param>
// Failed? /// <response code="200">Returned on valid request</response>
if (cat == null) /// <response code="404">Returned when no such category exists</response>
return NotFound(new { status = "error", error_msg = "Quote not found" }); [HttpDelete("{id}")]
[Authorize]
List<QuoteCategory> quoteLinks = await _db.QuoteCategories.Where(qc => qc.CategoryId == id).ToListAsync(); [EnableCors]
[ProducesResponseType(200)]
[ProducesResponseType(typeof(ErrorDTO), 404)]
public async Task<IActionResult> DeleteCategory(int id)
foreach (var link in quoteLinks) { {
_db.QuoteCategories.Remove(link); // (Attempt to) find the category
} Category? cat = await _db.Categories
_db.Categories.Remove(cat); .FirstOrDefaultAsync(c => c.Id == id);
// Failed?
await _db.SaveChangesAsync(); if (cat == null)
return NotFound(new { status = "error", error_msg = "Category not found" });
// ====================================================================== //
// Important! // // Find all the QuoteId <-> CategoryId pairs for provided id
// Is this the best we can do? Won't marking the quote as "hidden" // List<QuoteCategory> quoteLinks = await _db.QuoteCategories
// be better than explicitly deleting it? ~eee4 // .Where(qc => qc.CategoryId == id)
// ====================================================================== // .ToListAsync();
// Return ok // For each of the dependent quotes
return Ok(new { Status = "ok" }); foreach (var link in quoteLinks) {
// Remove all the associative pairs
_db.QuoteCategories.Remove(link);
}
// Finally, remove the category
_db.Categories.Remove(cat);
await _db.SaveChangesAsync();
// Return ok
return Ok(new { Status = "ok" });
} }
// TODO: Update category // TODO: Update category
// PATCH /api/v1/categories/1 // PATCH /api/v1/categories/1
// TODO: Delete category
// DELETE /api/v1/categories/1
} }

View File

@@ -181,64 +181,51 @@ public class QuotesController : ControllerBase
/// </summary> /// </summary>
/// <returns>A quote: id, quote content and author, imageUrl and categories if successful, otherwise: error message</returns> /// <returns>A quote: id, quote content and author, imageUrl and categories if successful, otherwise: error message</returns>
/// <response code="200">Returned on valid request</response> /// <response code="200">Returned on valid request</response>
/// <response code="404">Returned when no quotes exist</response> /// <response code="204">Returned when no quotes exist matching provided criteria</response>
/// <response code="404">Returned when no quotes exist in the DB</response>
[HttpGet("random")] [HttpGet("random")]
[AllowAnonymous] [AllowAnonymous]
[ProducesResponseType(typeof(QuoteShortDTO), 200)] [ProducesResponseType(typeof(QuoteShortDTO), 200)]
[ProducesResponseType(typeof(ErrorDTO), 404)]
[ProducesResponseType(204)] [ProducesResponseType(204)]
public async Task<IActionResult> GetRandomQuote([FromQuery] int? category_id = null) [ProducesResponseType(typeof(ErrorDTO), 404)]
{ public async Task<IActionResult> GetRandomQuote([FromQuery] int? category_id = null)
IQueryable<Quote> query = _db.Quotes.Include(q => q.QuoteCategories!).ThenInclude(qc => qc.Category); {
IQueryable<Quote> query = _db.Quotes
if (category_id.HasValue) .Include(q => q.QuoteCategories!)
{ .ThenInclude(qc => qc.Category);
query = query.Where(q => q.QuoteCategories!.Any(qc => qc.CategoryId == category_id.Value));
} if (category_id.HasValue)
{
var totalQuotes = await query.CountAsync(); query = query
if (totalQuotes == 0) .Where(q => q.QuoteCategories!
{ .Any(qc => qc.CategoryId == category_id.Value)
);
if (category_id.HasValue) }
return NoContent(); // Brak cytatów w wybranej kategorii
else var totalQuotes = await query.CountAsync();
return NotFound(new ErrorDTO { Status = "error", Error_msg = "No quotes to choose from" }); if (totalQuotes == 0)
} {
if (category_id.HasValue)
var random = new Random(); return NoContent(); // Brak cytatów w wybranej kategorii
var skip = random.Next(0, totalQuotes); else
return NotFound(new ErrorDTO { Status = "error", Error_msg = "No quotes to choose from" });
var quote = await query }
.Include(q => q.QuoteCategories!)
.ThenInclude(qc => qc.Category) var random = new Random();
.Skip(skip) var skip = random.Next(0, totalQuotes);
.Take(1)
.FirstOrDefaultAsync(); var quote = await query
.Include(q => q.QuoteCategories!)
if (quote == null) .ThenInclude(qc => qc.Category)
return NotFound(new ErrorDTO { Status = "error", Error_msg = "Unknown error - couldn't get quote" }); .Skip(skip)
.Take(1)
Image? image = null; .FirstOrDefaultAsync();
if (quote.ImageId != 0)
{ if (quote == null)
image = await _db.Images.FirstOrDefaultAsync(i => i.Id == quote.ImageId); return NotFound(new ErrorDTO { Status = "error", Error_msg = "Unknown error - couldn't get quote" });
}
return Ok(quote.ToQuoteShortDTO());
var dto = new QuoteShortDTO
{
Id = quote.Id,
Text = quote.Text,
Author = quote.Author,
ImageUrl = image?.Url,
Categories = quote.QuoteCategories?
.Select(qc => qc.Category?.Name ?? "")
.Where(name => !string.IsNullOrEmpty(name))
.ToList() ?? new List<string>()
};
return Ok(dto);
} }
// DELETE /api/v1/quotes/{id} // DELETE /api/v1/quotes/{id}