iiitl / iiitl/CForge

[Feature Request]: Add comprehensive unit tests for Service, Repository, and ViewModel layers

Open
#15 0 comments 0 reactions 0 assignees View on GitHub
enhancement hard work-medium
Dominant language
Swift
Stars
0
Forks
4
PR merge metrics
No merged PRs in 30d

Description

### Description:

The project currently has **zero functional tests** — the only test file (`CForgeTests.swift`) contains an empty placeholder. For a production app hitting a live API, this is a serious risk. The codebase already has protocol-based services (`ProblemServiceProtocol`) and clean separation of concerns, which makes it well-suited for unit testing.

### Current Behavior:

```swift
// CForgeTests.swift — the only test file
struct CForgeTests {
@Test func example() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
}
}
```

### Feature Requirements:

**Test Suite Structure:**

```
CForgeTests/
├── Services/
│ ├── ProblemServiceTests.swift
│ └── (ContestServiceTests.swift — if Issue #10 is completed)
├── Repositories/
│ └── ProblemRepositoryTests.swift
├── ViewModels/
│ ├── ProblemListViewModelTests.swift
│ └── ProblemSubmissionsViewModelTests.swift
├── Domain/
│ └── ProblemFilterEngineTests.swift
├── Models/
│ └── DecodingTests.swift
└── Mocks/
├── MockProblemService.swift
└── MockURLSession.swift
```

**Required Test Coverage:**

#### 1. `ProblemFilterEngine` Tests (Pure logic, easiest to test)
- Filter by title (case-insensitive)
- Filter by contest ID + index (e.g., "1234A")
- Filter by rating (numeric query)
- Filter by tag
- Combined query + tag filter
- Empty query returns all problems
- No matches returns empty array

#### 2. `ProblemRepository` Tests (Actor + caching)
- Fresh fetch when cache is empty
- Returns cached data within TTL
- Force refresh bypasses cache
- Cache expiry triggers a new fetch
- Concurrent requests are deduplicated (single network call for multiple callers)

#### 3. `ProblemListViewModel` Tests (State management)
- `loadProblems()` transitions: `.idle` → `.loading` → `.loaded`
- Network error transitions: `.idle` → `.loading` → `.error`
- `filterProblems()` updates `filteredProblems` correctly
- Duplicate `loadProblems()` calls while loading are ignored

#### 4. `ProblemService` Tests (Network layer — use mock URLSession)
- Successful API response → returns decoded problems
- Server error (non-200 status) → throws `NetworkError.serverError`
- Invalid JSON → throws `NetworkError.decodingError`
- Network failure → throws `NetworkError.transportError`

#### 5. Model Decoding Tests
- Decode valid `ProblemsResponse` JSON
- Decode `Submission` with all `Verdict` cases
- Decode `CodeforcesUser` with optional fields (nil `rating`, nil `rank`)
- Decode `RatingChange` for the chart data

### Key Files:

| Action | File |
|--------|------|
| **CREATE** | `CForgeTests/Mocks/MockProblemService.swift` |
| **CREATE** | `CForgeTests/Domain/ProblemFilterEngineTests.swift` |
| **CREATE** | `CForgeTests/Repositories/ProblemRepositoryTests.swift` |
| **CREATE** | `CForgeTests/ViewModels/ProblemListViewModelTests.swift` |
| **CREATE** | `CForgeTests/ViewModels/ProblemSubmissionsViewModelTests.swift` |
| **CREATE** | `CForgeTests/Services/ProblemServiceTests.swift` |
| **CREATE** | `CForgeTests/Models/DecodingTests.swift` |

### Expected Outcome:

- At least **25+ unit tests** across all layers.
- All tests pass when running `Cmd+U`.
- Mock implementations allow testing without hitting the live Codeforces API.
- `ProblemFilterEngine` has the highest coverage (pure logic, easy to cover completely).
- Test names follow the `test_methodName_condition_expectedResult` naming convention.

Contributor guide

Open the contributing guide

Research direction

Start with the empty CForgeTests.swift placeholder and inspect the listed service, repository, ViewModel, domain, and model files to understand their protocols and state transitions. Create the requested mocks and test files, beginning with ProblemFilterEngineTests.swift and model decoding tests before covering caching and network behavior. Done means at least 25 unit tests pass with Cmd+U without contacting the live Codeforces API.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.