Skip to content

Latest commit

 

History

History
201 lines (155 loc) · 5.7 KB

File metadata and controls

201 lines (155 loc) · 5.7 KB

CardTrackerWeb

A full-stack ASP.NET Core web application for managing and importing card game decks with a layered architecture, unit tests, and CI/CD pipeline. Created with the initial motivation of inspiring deck-building creativity by enabling me to see which cards I have yet to include in decks.

.NET Tests

Tech Stack

Layer Technology
Framework ASP.NET Core 8+ MVC
ORM Entity Framework Core
Database SQLite
Testing xUnit, Moq
Frontend Razor Views, HTML5, CSS3
CI/CD GitHub Actions

Project Architecture

CardTrackerWeb/
├── CardTrackerWebMainProj/
│   ├── Controllers/              # HTTP request handlers
│   ├── BLL/ (Business Logic Layer)
│   │   ├── Interfaces/
│   │   └── Services/
│   ├── DAL/ (Data Access Layer)
│   │   ├── Interfaces/
│   │   └── Repositories/
│   ├── Models/                   # Domain entities
│   ├── Data/                     # EF Core DbContext
│   ├── Views/                    # Razor templates
│   └── Program.cs                # DI configuration & app setup
│
└── CardTrackerWeb.Tests/         # Unit test project

Design Patterns & Principles

Layered Architecture

  • Presentation Layer: Controllers + Razor Views handle HTTP requests/responses
  • Business Logic Layer: Services encapsulate business rules and workflows
  • Data Access Layer: Repositories abstract database operations via EF Core

Dependency Injection

All services registered in Program.cs using ASP.NET Core's built-in DI container:

builder.Services.AddScoped<ICardService, CardService>();
builder.Services.AddScoped<IDeckService, DeckService>();
builder.Services.AddSingleton<ICardListParser, ThronesDbJsonCardListParser>();

Key Interfaces (Abstraction)

  • ICardListParser - Parses card data from external JSON sources
  • IDeckImporter - Imports deck lists from user-provided text format
  • ICardService / IDeckService - Business logic for cards and decks
  • ICardRepo / IDeckRepo - Database persistence abstraction

Features

Deck Management

  • ✅ Create, read, update, and delete decks
  • ✅ Full deck composition visibility with card details
  • ✅ Persistent storage with SQLite

Deck Import

  • ✅ Parse ThronesDB .txt deck format
  • ✅ Validate and normalize imported card data
  • ✅ Handle import errors with meaningful feedback

Card Database

  • ✅ Load card metadata from ThronesDB JSON API
  • ✅ Card search and filtering by faction

Getting Started

Prerequisites

  • .NET 8 SDK or later
  • SQLite

Installation

  1. Clone the repository

    git clone {this repository}
    cd CardTrackerWeb
  2. Restore dependencies

    dotnet restore
  3. Run the application

    cd CardTrackerWebMainProj
    dotnet run

    The app will automatically seed the database on first run.

  4. Open in browser

    https://localhost:5001
    

Running Tests

# Run all tests
dotnet test

# Run with verbose output
dotnet test --verbosity detailed

# Run specific test class
dotnet test --filter "ClassName=DeckServiceTests"

Usage Examples

Importing a Deck

  1. Navigate to DecksImport
  2. Paste a ThronesDB deck list (.txt format)
  3. Application validates format and imports cards
  4. View imported deck in Decks list with full composition

Managing Decks

  • View: Click a deck to see all cards, constraints, and metadata
  • Edit: Update deck name and description
  • Delete: Permanently remove a deck

Testing Strategy

Unit Tests (DeckServiceTests.cs)

  • Service isolation: Mocked repositories and dependencies using Moq
  • Happy path: Successful deck import with valid data
  • Error cases: Unknown faction, missing cards, validation failures
  • Verification: Assert that repositories receive correct data

Example:

[Test]
public async Task ImportDeck_WhenImporterParsesDeckString_ShouldReturnSuccessWithId()
{
    // Arrange
    var mockRepo = new Mock<IDeckRepo>();
    var deckService = new DeckService(mockRepo.Object, ...);

    // Act
    var result = await deckService.ImportDeckFromString("deck string", "owner", "name");

    // Assert
    Assert.That(result.Status, Is.EqualTo(DeckImportStatus.Success));
    mockRepo.Verify(r => r.InsertDeck(It.IsAny<Deck>()), Times.Once);
}

Parser Tests (ThronesdbJsonParserTest.cs)

  • Nullable field handling (cost, strength, etc.)
  • Complete card property coverage

Test Coverage

  • Service layer: Business logic and workflows
  • Parser layer: JSON deserialization and validation
  • Edge cases: Null values, invalid data, missing resources

Configuration

Update appsettings.json for database and API settings:

{
  "ConnectionStrings": {
    "LocalSQLiteCardTrackerDb": "Data Source=cardtracker.db"
  }
}

SQLite database file will be created automatically on first run.

CI/CD Pipeline

GitHub Actions automatically:

  • ✅ Builds the solution
  • ✅ Runs all unit tests
  • ✅ Reports test coverage
  • ✅ Validates code style

View workflow: .github/workflows/dotnet.yml

Development Notes

External Dependencies

  • ThronesDB API - Card data fetched on application startup (requires internet)
  • SQLite - Local database stored in project directory

Database

  • Schema created model-first by EF Core. Migrations can be found in CardTrackerWebMainProj/Migrations
  • Seeding happens during application initialization