Spring Boot Using JSP
Spring Boot Using JSP
CONTENTS
1 Introduction
10 Conclusion
Developing the system, which meets the SRS and solving all
the requirements of the system.
SOFTWARE REQUIREMENTS:-
JDK 17.0.8
COCOMO MODEL
The Constructive Cost Model (COCOMO) is an algorithm software cost
estimation model developed by Barry Bohem. The model uses a
basic Regression formula, with parameters that are derived from
historical project data and current project characteristics.
Ei=a*(KDLOC)b
The value of the constant a and b are depends on the project type
Accordingly,
Effort =a*(KLOC) PM
Thus, Eduleam E-learning Platform requires effort of person per month and
time require for development is 4.6 months(approx.)
ENTITY RELATIONSHIP DIAGRAM
In software engineering, an entity–relationship model(ER model)
is a data model for describing the data or information aspects of a
business domain or its process requirements, in an abstract way that
lends itself to ultimately being implemented in a database such as a
relational. The main components of ER models are entities (things)
and the relationships that can exist among them.
An entity–relationship model is the result of using a systematic
process to describe and define a subject area of business data. It
does not define business process; only visualize business data. The
data is represented as components (entities) that are linked with
each other by relationships that express the dependencies and
requirements between them, such as: one building may be
divided into zero or more apartments, but one apartment can
only be located in onebuilding. Entities may have various
properties (attributes) that characterize them. Diagrams created
to represent these entities,
attributes, and relationships graphically are called entity–relationship
diagrams.
An ER model is typically implemented as a database. In the case of
a relational database, which stores data in tables, every row of
each table represents one instance of an entity. Some data fields in
these
tables point to indexes in other tables; such pointers are the physical
implementation of the relationships.
The three schema approach to software engineering uses three
levels of ER models that may be developed.
Logical data model: The logical ER model contains more detail than
the conceptual ERmodel. In addition to master data entities,
operational andtransactional data entities are now defined. The
details of each dataentity are developed and the relationships
between these data entities are established. The logical ER model is
however developed independent of technology into which it can be
implemented.
CARDINALITY:
Cardinality constraints are expressed as follows:
A double line indicates a participation constraint, totality or
subjectivity : all entities in the entity set must participate in
at least one relationship in the relationship set;
an arrow from entity set to relationship set indicates a key
constraint, i.e. injectivity: each entity of the entity set can
participate in at most one relationship in the relationship
set;
A thick line indicates both, i.e. bijectivity: each entity in
the entity set is involved in exactly one relationship.
An underlined name of an attribute indicates that it is a key:
two different entities or relationships with this attribute
always have different values for this attribute.
ER-DIAGRAM
DATA FLOW DIAGRAM
A data flow diagram (DFD) is a graphical representation of the
"flow" of data through an information system, modelling its process
aspects. A DFD is often used as a preliminary step to create an
overview of the system, which can later be elaborated.
DFDs can also be used for the visualization of data processing
(structured design).
Data flow diagrams can be used in both Analysis and Design phase of
the SDLC.
DFD NOTATION:
Steps to Construct Data Flow Diagram:-
1. USER REGISTRATION
BACKEND:
package com.backend.edulearn.controller;
import com.backend.edulearn.entity.User;
import java.util.List;
import com.backend.edulearn.repository.UserRepository;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "http://localhost:3000") // Specify the allowed origin for CORS
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping("/register")
public ResponseEntity<?> registerUser(@RequestBody User user) {
// Check if the email or phone number already exists
User existingUserByEmail = userRepository.findByUemail(user.getUemail());
User existingUserByPhone = userRepository.findByUphno(user.getUphno());
if (existingUserByEmail != null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Email already exists");
}
if (existingUserByPhone != null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Phone number already exists");
}
@GetMapping("/check-exists")
public ResponseEntity<?> checkExistingUser(@RequestParam String email, @RequestParam String phone)
{ User existingUserByEmail = userRepository.findByUemail(email);
User existingUserByPhone = userRepository.findByUphno(phone);
package com.backend.edulearn.controller;
import com.backend.edulearn.entity.User;
import java.util.List;
import com.backend.edulearn.repository.UserRepository;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "http://localhost:3000") // Specify the allowed origin for CORS
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping("/reset-password")
public ResponseEntity<?> resetPassword(@RequestBody Map<String, String>
requestData) {
String emailOrPhone = requestData.get("emailOrPhone");
String newPassword = requestData.get("newPassword");
String confirmPassword = requestData.get("confirmPassword");
if (user == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not
found");
}
if (!newPassword.equals(confirmPassword)) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Passwords do
not match");
}
try {
// Save the updated user in the database
User updatedUser = userRepository.save(user);
return ResponseEntity.ok("Password updated successfully for user: " +
updatedUser.getUname());
} catch (Exception e) {
return
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error updating
password");
}
}
3. ADD COURSE
FRONTEND :
try {
const response = await
axios.post('http://localhost:8080/api/courses/create', formData);
if (response.status === 201)
{ toast.success('Course added
successfully'); setCourse({
courseTitle: '',
description: '',
thumbnailFile: null,
videoFiles: [],
courseCategory: '',
mentorEmail: '',
});
setTimeout(() => {
window.location.reload();
}, 2000);
} else {
toast.error('Failed to add course. Please try again later.');
}
} catch (error) {
toast.error(`Something went wrong: ${error.message}`);
}
};
return (
<div style={{
backgroundImage:
'url("/bgh.jpg")',
backgroundSize: 'cover',
minHeight: '100vh',
display: 'flex',
justifyContent:
'center', alignItems:
'center'
}}>
<div
style={{ width:
'400px',
padding:
'20px',
backgroundColor: 'rgba(255, 255, 255, 0.8)',
boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.1)'
}}>
<h1 className="mb-4 text-center">Add New Course</h1>
<Form onSubmit={handleSubmit}>
<FormGroup>
<Label for="courseTitle">Course Title</Label>
<Input type="text" name="courseTitle" id="courseTitle"
value={course.courseTitle} onChange={handleInputChange} />
</FormGroup>
<FormGroup>
<Label for="description">Course Description</Label>
<Input type="textarea" name="description" id="description"
value={course.description} onChange={handleInputChange} />
</FormGroup>
<FormGroup>
<Label for="thumbnailFile">Thumbnail (Choose File)</Label>
<Input type="file" name="thumbnailFile" id="thumbnailFile"
onChange={handleThumbnailChange} />
</FormGroup>
<FormGroup>
<Label for="videoFiles">Course Videos (Choose Files)</Label>
<Input type="file" name="videoFiles" id="videoFiles"
multiple onChange={handleVideoChange} />
</FormGroup>
<FormGroup>
<Label for="courseCategory">Course Category</Label>
<Input type="select" name="courseCategory"
id="courseCategory" value={course.courseCategory}
onChange={handleInputChange}>
<option value="">Select Category</option>
<option value="Programming Languages">Programming Languages</option>
<option value="Business & Management">Business & Management</option>
<option value="Data Science">Data Science</option>
<option value="AI and Machine Learning">AI and Machine
Learning</option>
<option value="Art & Design">Art & Design</option>
<option value="Health & Wellness">Health & Wellness</option>
<option value="JEE">JEE</option>
<option value="Board Exams">Board Exams</option>
</Input>
</FormGroup>
<FormGroup>
<Label for="mentorEmail">Mentor's Email</Label>
<Input type="email" name="mentorEmail" id="mentorEmail"
value={course.mentorEmail} onChange={handleInputChange} />
</FormGroup>
<Button color="primary" type="submit">Add Course</Button>
</Form>
</div>
</div>
);
};
BACKEND :
package com.backend.edulearn.controller;
import com.backend.edulearn.entity.CourseVideo;
import com.backend.edulearn.services.CourseVideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/courses")
@CrossOrigin(origins = "http://localhost:3000") // Specify the allowed origin for CORS
public class CourseVideoController {
@PostMapping("/create")
public ResponseEntity<String> createCourse(@ModelAttribute CourseVideo
courseVideo) {
try {
courseVideoService.saveCourseVideo(courseVideo);
return new ResponseEntity<>("Course created successfully",
HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>("Failed to create course",
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
4,COURSES
FRONTEND:
useEffect(() => {
fetchCourses();
}, []);
useEffect(() => {
if (studentEmail) {
checkEnrollments(courses);
}
}, [studentEmail, courses, checkEnrollments]);
return (
<div className="courses-container" style={{ backgroundColor: 'rgb(222,
227, 227, 1)', display: 'flex', flexWrap: 'wrap', gap: '20px', padding:
'20px' }}>
{courses.map(course => (
<div key={course.courseId} className="course-card" style={{
width: '300px', boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)', borderRadius:
'8px', overflow: 'hidden', backgroundColor: '#fff' }}>
<div className="thumbnail-container" style={{ position:
'relative', cursor: 'pointer' }}>
<img src={`http://localhost:8080${course.thumbnailUrl}`}
alt="Course Thumbnail" className="course-thumbnail" style={{ width: '100%',
height: 'auto', objectFit: 'cover' }} />
<div className="play-button" style={{ position:
'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
backgroundColor: 'rgba(0, 0, 0, 0.6)', borderRadius: '50%', width: '50px',
height: '50px', display: 'flex', justifyContent: 'center', alignItems:
'center' }} onClick={() => handlePlayClick(course)}>
<span style={{ color: '#fff', fontSize: '24px' }}>▶
</span>
</div>
</div>
<div className="course-details" style={{ padding: '10px' }}>
<h3 style={{ marginBottom: '5px'
}}>{course.courseTitle}</h3>
<p style={{ fontSize: '14px', color: '#333'
}}><strong>Description:
</strong>{course.description}</p>
{enrollments[course.courseId] ? (
<button className="watch-button" style={{
backgroundColor: '#4CAF50', color: '#fff', border: 'none', padding: '6px 10px',
width: 'auto', cursor: 'pointer', marginTop: '10px' }} onClick={() =>
navigate(`/video/${course.courseId}`)}>Watch Now</button>
) : (
<button className="enroll-button" style={{
backgroundColor: '#7C67FF', color: '#fff', border: 'none', padding: '6px 10px',
width: 'auto', cursor: 'pointer', marginTop: '10px' }} onClick={() =>
handleEnrollNow(course.courseId)}>Enroll Now</button>
)}
</div>
</div>
))}
<ToastContainer />
{showAlert && (
<Alert severity="error" variant="filled" onClose={() =>
setShowAlert(false)} sx={{ position: 'fixed', top: '50%', left: '50%',
transform: 'translate(-50%, -50%)', zIndex: 9999, width: '400px', textAlign:
'center', fontSize: '1.2rem' }}>
Please Login/Signup First.
</Alert>
)}
</div>
);
};
BACKEND:
package com.backend.edulearn.controller;
import com.backend.edulearn.entity.CourseVideo;
import com.backend.edulearn.services.CourseVideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/courses")
@CrossOrigin(origins = "http://localhost:3000") // Specify the allowed origin for CORS
public class CourseVideoController {
@GetMapping("/all")
public ResponseEntity<List<CourseVideo>> getAllCourseVideos()
{ List<CourseVideo> courseVideos = courseVideoService.getAllCourseVideos();
return new ResponseEntity<>(courseVideos, HttpStatus.OK);
}
5.FEEDBACK
BACKEND:
package com.backend.edulearn.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.backend.edulearn.entity.Feedback;
import com.backend.edulearn.repository.FeedbackRepository;
@RestController
@RequestMapping("/api/feedback")
@CrossOrigin(origins = "http://localhost:3000") // Specify the allowed origin for CORS
@Autowired
private FeedbackRepository feedbackRepository;
@PostMapping("/save")
public ResponseEntity<Feedback> submitFeedback(@RequestBody Feedback feedback)
{ Feedback savedFeedback = feedbackRepository.save(feedback);
return ResponseEntity.ok(savedFeedback);
}
@GetMapping("/{courseId}")
public ResponseEntity<List<Feedback>> getFeedbacksByCourseId(@PathVariable String courseId)
{ List<Feedback> feedbacks = feedbackRepository.findByCourseId(courseId);
return ResponseEntity.ok(feedbacks);
}
}
IMPLEMENTATION & TESTING
A software system test plan is a document that describes the
objectives, scope, approach and focus of software testing effort. The
process of preparing a test plan is a usual way to think the efforts
needed to validate the acceptability of a software product. The
complete document will help people outside the test group
understand the "WHY" and "HOW" product validation. It should be
through enough to be useful but not so through that no one outside
the test group will read it.
INTRODUCTION
The objective our test plan is to find and report as many bugs as
possible to improve the integrity of our program. Although
exhaustive testing is not possible, we will exercise a broad range of
tests to achieve our goal. Our user interface to utilize these functions
is designed to be user-friendly and provide easy manipulation of the
tree. The application will only be used as a demonstration tool, but
we would like to ensure that it could be run from a variety of
platforms with little impact on performance or usability.
Process Overview:
3. Review the test data and test cases to ensure that the unit has
been thoroughly verified and that the test data and test cases are
adequate to verify proper operation of the unit.
7. Document the test data, test cases, and test configuration used
during the testing process. This information shall be submitted via
the Unit/System Test Report (STR).
TEST CASES:
TESTING STEPS
Unit Testing:
Unit testing focuses efforts on the smallest unit of software design. This
is known as module testing. The modules are tested separately. The
test is carried out during programming stage itself. In this step, each
module is found to be working satisfactory as regards to the
expected output from the module.
Integration Testing:
Data can be lost across an interface. One module can have an adverse
effect on another, sub functions, when combined, may not be
linked in desired manner in major functions. Integration testing is a
systematic approach for constructing the program structure, while
at the same time conducting test to uncover errors associated within
the interface. The objective is to take unit tested modules and builds
program structure. All the modules are combined and tested as a
whole.
Validation:
Test Case 1
Number
Test Case Name User Login
Test Case The user should enter his/ her accurate mail- id
Description and password so that he/she can able to go
for the further options. The test case will
check the application for the same since a
user can only login with the correct user id,
password.
Item(s) to be tested
Specifications
Negative:
Positive:
Tested By: Shubhodeep Mandal
Item(s) to be tested
Specifications
Expected
Input Output/Result
1) Registered mail-id and password 1) Email already exists
Negative:
Positive:
WHITE BOX TESTING
System Testing
The goals of system testing are to detect faults that can only be
exposed by testing the entire integrated system or some major part
of it. Generally, system testing is mainly concerned with areas such
as performance, security, validation, load/stress, and configuration
sensitivity. But in our case well focus only on function validation and
performance. And in both cases we will use the black-box method
of testing.
OUTPUT TESTING
"Program testing can be used to slow the presence of bug, but never to
slow their absence." If the results delivered by the system are
different from the excepted ones then the system is incorrect and
these bugs should be fixed.
FUTURE SCOPE AND FURTHER ENHANCEMENTS
With online courses, learners set their own goals, at their own pace
while learning and going through learning materials. This is a unique
advantage that online education provides to all its learners. It helps
learners navigate through their learning path and achieve their
personal goals by connecting with the instructor and other learners.
With online courses, learners set their own goals, at their own pace
while learning and going through learning materials. This is a unique
advantage that online education provides to all its learners. It helps
learners navigate through their learning path and achieve their
personal goals by connecting with the instructor and other learners.
https://www.w3schools.com
https://www.slideshare.com
https://www.scribd.com
https://www.tutorialspoint.com
https://www.geeksforgeeks.org.com
https://www.youtube.com
https://www.javatpoint.com
THANK YOU