diff --git a/.editorconfig b/.editorconfig index 54e72f7..7c7dc28 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,5 @@ [*] -end_of_line = crlf +end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true \ No newline at end of file diff --git a/Controllers/CategoryController.cs b/Controllers/CategoryController.cs index 9770b00..aab55e8 100644 --- a/Controllers/CategoryController.cs +++ b/Controllers/CategoryController.cs @@ -108,48 +108,55 @@ public class CategoryController : ControllerBase // And send back to the user as DTO return Ok(cat.ToCategoryShortDTO()); - } - - [HttpDelete("{id}")] - [Authorize] - [EnableCors] - [ProducesResponseType(200)] - [ProducesResponseType(typeof(ErrorDTO), 404)] - public async Task DeleteCategory(int id) - { - // (Attempt to) find the quote - Category? cat = await _db.Categories - .FirstOrDefaultAsync(c => c.Id == id); - // Failed? - if (cat == null) - return NotFound(new { status = "error", error_msg = "Quote not found" }); - - List quoteLinks = await _db.QuoteCategories.Where(qc => qc.CategoryId == id).ToListAsync(); - - - - foreach (var link in quoteLinks) { - _db.QuoteCategories.Remove(link); - } - _db.Categories.Remove(cat); - - await _db.SaveChangesAsync(); - - // ====================================================================== // - // Important! // - // Is this the best we can do? Won't marking the quote as "hidden" // - // be better than explicitly deleting it? ~eee4 // - // ====================================================================== // - - // Return ok - return Ok(new { Status = "ok" }); + } + + // DELETE /api/v1/categories + /// + /// [AUTHED] Delete a category + /// + /// + /// Allows authorized users to delete categories. + ///

+ /// Has CORS set. + ///
+ /// Id of the category which shall be deleted + /// Returned on valid request + /// Returned when no such category exists + [HttpDelete("{id}")] + [Authorize] + [EnableCors] + [ProducesResponseType(200)] + [ProducesResponseType(typeof(ErrorDTO), 404)] + public async Task DeleteCategory(int id) + { + // (Attempt to) find the category + Category? cat = await _db.Categories + .FirstOrDefaultAsync(c => c.Id == id); + // Failed? + if (cat == null) + return NotFound(new { status = "error", error_msg = "Category not found" }); + + // Find all the QuoteId <-> CategoryId pairs for provided id + List quoteLinks = await _db.QuoteCategories + .Where(qc => qc.CategoryId == id) + .ToListAsync(); + + // For each of the dependent quotes + 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 // PATCH /api/v1/categories/1 - // TODO: Delete category - // DELETE /api/v1/categories/1 - } - + diff --git a/Controllers/QuoteController.cs b/Controllers/QuoteController.cs index 9f1a4cd..c9cca5e 100644 --- a/Controllers/QuoteController.cs +++ b/Controllers/QuoteController.cs @@ -181,64 +181,51 @@ public class QuotesController : ControllerBase /// /// A quote: id, quote content and author, imageUrl and categories if successful, otherwise: error message /// Returned on valid request - /// Returned when no quotes exist + /// Returned when no quotes exist matching provided criteria + /// Returned when no quotes exist in the DB [HttpGet("random")] [AllowAnonymous] [ProducesResponseType(typeof(QuoteShortDTO), 200)] - [ProducesResponseType(typeof(ErrorDTO), 404)] [ProducesResponseType(204)] - public async Task GetRandomQuote([FromQuery] int? category_id = null) - { - IQueryable query = _db.Quotes.Include(q => q.QuoteCategories!).ThenInclude(qc => qc.Category); - - if (category_id.HasValue) - { - query = query.Where(q => q.QuoteCategories!.Any(qc => qc.CategoryId == category_id.Value)); - } - - var totalQuotes = await query.CountAsync(); - if (totalQuotes == 0) - { - - if (category_id.HasValue) - return NoContent(); // Brak cytatów w wybranej kategorii - else - return NotFound(new ErrorDTO { Status = "error", Error_msg = "No quotes to choose from" }); - } - - var random = new Random(); - var skip = random.Next(0, totalQuotes); - - var quote = await query - .Include(q => q.QuoteCategories!) - .ThenInclude(qc => qc.Category) - .Skip(skip) - .Take(1) - .FirstOrDefaultAsync(); - - if (quote == null) - return NotFound(new ErrorDTO { Status = "error", Error_msg = "Unknown error - couldn't get quote" }); - - Image? image = null; - if (quote.ImageId != 0) - { - image = await _db.Images.FirstOrDefaultAsync(i => i.Id == quote.ImageId); - } - - 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() - }; - - return Ok(dto); - + [ProducesResponseType(typeof(ErrorDTO), 404)] + public async Task GetRandomQuote([FromQuery] int? category_id = null) + { + IQueryable query = _db.Quotes + .Include(q => q.QuoteCategories!) + .ThenInclude(qc => qc.Category); + + if (category_id.HasValue) + { + query = query + .Where(q => q.QuoteCategories! + .Any(qc => qc.CategoryId == category_id.Value) + ); + } + + var totalQuotes = await query.CountAsync(); + if (totalQuotes == 0) + { + if (category_id.HasValue) + return NoContent(); // Brak cytatów w wybranej kategorii + else + return NotFound(new ErrorDTO { Status = "error", Error_msg = "No quotes to choose from" }); + } + + var random = new Random(); + var skip = random.Next(0, totalQuotes); + + var quote = await query + .Include(q => q.QuoteCategories!) + .ThenInclude(qc => qc.Category) + .Skip(skip) + .Take(1) + .FirstOrDefaultAsync(); + + if (quote == null) + return NotFound(new ErrorDTO { Status = "error", Error_msg = "Unknown error - couldn't get quote" }); + + return Ok(quote.ToQuoteShortDTO()); + } // DELETE /api/v1/quotes/{id}