CSC/ECE 517 Fall 2025 - E2561. Finish up SubmittedContentController: Difference between revisions
No edit summary |
|||
| Line 369: | Line 369: | ||
* RSpec & FactoryBot documentation | * RSpec & FactoryBot documentation | ||
* Robert C. Martin – ''Clean Architecture and SOLID Principles'' | * Robert C. Martin – ''Clean Architecture and SOLID Principles'' | ||
---- | ---- | ||
Revision as of 04:47, 11 November 2025
Project Overview
This project, E2561, is a direct continuation of E2551: Reimplementing SubmittedContentController.
The previous phase (E2551) reimplemented the `SubmittedContentController` in the reimplementation-back-end repository, providing the base functionality for managing student submissions — uploading files, submitting hyperlinks, and deleting existing submissions.
While the core endpoints were implemented, comprehensive testing and full design refactoring remain incomplete. The goal of this phase is to **finalize and harden** the controller by:
- Developing a robust **RSpec test suite**
- Performing a deep **OODD and SOLID refactor**
- Updating **inline and Swagger documentation**
This ensures that the controller is production-ready, maintainable, and compliant with sound software-engineering principles.
Background
The `SubmittedContentController` currently manages:
- File and hyperlink submission endpoints
- View and delete operations for student submissions
- Helper logic for upload/delete actions
Limitations identified in E2551:
- Partial or missing RSpec tests
- Controller performing multiple responsibilities
- Reusable logic buried inside controller methods rather than helpers/services
- Minor naming inconsistencies and unclear documentation
Objectives
| Category | Goals | Non-Goals |
|---|---|---|
| Testing | Achieve ≥90% RSpec coverage for all controller and helper methods | UI / front-end testing |
| Refactoring | Apply OODD and SOLID principles; extract services and simplify logic | Adding new user-facing features |
| Documentation | Improve inline comments and Swagger endpoint examples | Full redesign of Swagger UI |
Design and Implementation Plan
The project focuses on two major pillars: Comprehensive Testing and OODD/SOLID Refactoring.
1. Comprehensive Testing Plan
Purpose: Ensure correctness, robustness, and predictable behavior of all controller actions.
Scope:
- Unit tests for helper and service methods
- Controller tests for `create`, `show`, and `destroy`
- Integration tests for end-to-end submission handling
- Validation of proper HTTP codes and JSON messages
Frameworks & Tools:
- RSpec
- FactoryBot
- DatabaseCleaner
- SimpleCov
- Faker
Example Test Cases:
| Action | Scenario | Expected Response |
|---|---|---|
| POST /submitted_content | Valid file upload | 200 OK – success message |
| POST /submitted_content | Invalid file type | 400 Bad Request – error message |
| DELETE /submitted_content/:id | Authorized user deletes submission | 204 No Content |
| DELETE /submitted_content/:id | Unauthorized user | 403 Forbidden |
| POST /submitted_content | Valid hyperlink | 201 Created |
| POST /submitted_content | Empty hyperlink | 422 Unprocessable Entity |
| GET /submitted_content | Valid participant | 200 OK with JSON submissions |
| GET /submitted_content | Invalid participant | 404 Not Found |
Coverage Target: > Minimum 90% overall line coverage for controller and helpers.
2. OODD and SOLID Refactor Plan
Goal: Refactor the controller so each component has a single responsibility and can evolve without modification.
| Principle | Implementation Plan |
|---|---|
| Single Responsibility | Extract file and hyperlink logic into dedicated service classes (`FileSubmissionService`, `HyperlinkSubmissionService`) |
| Open/Closed | Controller open for extension but closed for modification – new submission types can be added without editing controller |
| Liskov Substitution | Introduce a common `SubmissionService` interface for polymorphism |
| Interface Segregation | Split helper functions into granular validation utilities |
| Dependency Inversion | Inject service objects instead of directly instantiating concrete classes |
Proposed Directory Structure:
app/
├── controllers/
│ └── submitted_content_controller.rb
├── services/
│ ├── file_submission_service.rb
│ └── hyperlink_submission_service.rb
├── helpers/
│ └── submission_helper.rb
└── specs/
├── controllers/
├── services/
└── helpers/
Example Service Stub:
class FileSubmissionService
def initialize(file, participant)
@file = file
@participant = participant
end
def upload
# handle validations, storage, and error handling
end
def delete
# clean up file and DB records
end
end
UML Diagrams
To visualize the evolution of the `SubmittedContentController` design, the following UML diagrams highlight the pre-refactor structure, refactored structure, and the runtime file upload flow.
1. Pre-Refactor Structure
The initial design from E2551 placed most logic within the controller, directly handling validations, database access, and file operations.
<plantuml> @startuml class SubmittedContentController {
+create() +show() +destroy()
}
class SubmissionHelper {
+validate_file() +validate_hyperlink() +delete_submission()
}
class SubmittedContent {
+id +participant_id +url +file_path
}
SubmittedContentController --> SubmissionHelper : uses SubmittedContentController --> SubmittedContent : accesses directly @enduml </plantuml>
Observation:
- Controller mixed validation, persistence, and routing responsibilities.
- No separation of file and hyperlink handling.
- Hard to test and extend.
2. Refactored Design (E2561 Target)
After refactoring, submission logic is delegated to dedicated service classes following SOLID principles. The controller now acts as an orchestrator.
<plantuml> @startuml interface SubmissionService {
+upload() +delete()
}
class FileSubmissionService implements SubmissionService {
-file -participant +upload() +delete()
}
class HyperlinkSubmissionService implements SubmissionService {
-url -participant +upload() +delete()
}
class SubmittedContentController {
-service : SubmissionService +create() +show() +destroy() +set_service(type)
}
class SubmissionHelper {
+validate_file() +validate_hyperlink()
}
class SubmittedContent {
+id +participant_id +url +file_path
}
SubmittedContentController --> SubmissionService : delegates FileSubmissionService --> SubmittedContent : creates/updates HyperlinkSubmissionService --> SubmittedContent : creates/updates SubmissionService <|.. FileSubmissionService SubmissionService <|.. HyperlinkSubmissionService SubmittedContentController --> SubmissionHelper : uses @enduml </plantuml>
Key Benefits:
- Each class has a single, clear responsibility.
- The controller depends on abstractions, not implementations.
- Easier testing via dependency injection.
- Future submission types can be added with minimal changes.
3. Sequence Diagram: File Upload Flow
Demonstrates the runtime interaction when a student uploads a file.
<plantuml> @startuml actor Student participant SubmittedContentController participant FileSubmissionService participant SubmissionHelper participant SubmittedContent
Student -> SubmittedContentController : POST /submitted_content (file) SubmittedContentController -> SubmissionHelper : validate_file(file) SubmissionHelper --> SubmittedContentController : validation result SubmittedContentController -> FileSubmissionService : upload(file, participant) FileSubmissionService -> SubmittedContent : save(file metadata) SubmittedContent --> FileSubmissionService : success FileSubmissionService --> SubmittedContentController : confirmation SubmittedContentController --> Student : JSON { message: "Uploaded successfully" } @enduml </plantuml>
Advantages:
- Controller delegates validation and persistence.
- Simplified data flow improves maintainability and testability.
Testing Strategy and Workflow
| Level | Tool | Focus |
|---|---|---|
| Unit | RSpec | Individual helper and service methods |
| Controller | RSpec | API response codes, JSON messages, authorization |
| Integration | RSpec + DatabaseCleaner | End-to-end upload/delete flow and DB consistency |
| Coverage | SimpleCov | Maintain ≥90% coverage |
Workflow Steps:
- Configure RSpec environment (`rails_helper`, `spec_helper`)
- Implement controller tests first (black-box)
- Add service-level unit tests
- Add integration tests for file and hyperlink flows
- Verify coverage via SimpleCov
Documentation Updates
- Add method-level docstrings for all refactored and new service methods
- Update Swagger API documentation:
- Confirm endpoint names, parameters, and responses
- Add example request/response bodies for both file and hyperlink submissions
- Include SimpleCov coverage screenshot and Swagger snippet in final wiki deliverable
Example Swagger Path:
/submitted_content:
post:
summary: Upload submitted content (file or hyperlink)
responses:
"200":
description: Successfully uploaded
"400":
description: Invalid input or file type
Task Breakdown
| Category | Task | Description |
|---|---|---|
| Testing | Implement controller RSpec tests | Cover all success and failure cases |
| Add service unit tests | Validate file and hyperlink logic | |
| Add integration tests | Ensure correct database and filesystem behavior | |
| Refactoring | Extract FileSubmissionService | Isolate file handling from controller |
| Extract HyperlinkSubmissionService | Encapsulate hyperlink logic | |
| Apply dependency injection | Improve modularity and testing | |
| Documentation | Update Swagger and comments | Reflect refactored structure and responses |
| Add SimpleCov report screenshot | Demonstrate achieved coverage |
Timeline
| Week | Milestone |
|---|---|
| Week 1 | Set up RSpec environment, write controller tests |
| Week 2 | Extract services and write unit tests |
| Week 3 | Add integration tests, finalize docs and Swagger updates |
Expected Outcomes
- Comprehensive RSpec suite with robust edge-case coverage
- ≥90% test coverage verified by SimpleCov
- Fully SOLID/OODD-compliant controller design
- Simplified and maintainable backend logic
- Updated Swagger and inline documentation
References
- E2551 Wiki Page
- [E2551 PR #224](https://github.com/expertiza/reimplementation-back-end/pull/224)
- RSpec & FactoryBot documentation
- Robert C. Martin – Clean Architecture and SOLID Principles
Team Members and Mentor
| Name | Unity ID |
|---|---|
| Aanand Sreekumaran Nair Jayakumari | asreeku |
| Aastha Gaudani | agaudan |
| Raghav Tippani Kesari | rtippan |
| Faculty Mentor: Prof. Edward Gehringer | efg |