Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
W
WebBack
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
websystem
WebBack
Commits
490d41b6
Commit
490d41b6
authored
6 months ago
by
tpgus2603
Browse files
Options
Downloads
Patches
Plain Diff
test,refactor 서비스로직 관련 테스트 및 리팩토링
parent
fd2daa22
No related branches found
No related tags found
2 merge requests
!31
Develop
,
!14
[#11] dto설정, 프렌드,서비스로직 테스트 및 로직변경
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
services/schedule.test.js
+53
-42
53 additions, 42 deletions
services/schedule.test.js
services/scheduleService.js
+242
-222
242 additions, 222 deletions
services/scheduleService.js
with
295 additions
and
264 deletions
services/schedule.test.js
+
53
−
42
View file @
490d41b6
...
...
@@ -4,7 +4,7 @@ const sequelize = require('../config/sequelize');
const
User
=
require
(
'
../models/User
'
);
const
Friend
=
require
(
'
../models/Friend
'
);
const
Schedule
=
require
(
'
../models/Schedule
'
);
const
scheduleService
=
require
(
'
.
./services
/scheduleService
'
);
// scheduleService 임포트
const
scheduleService
=
require
(
'
./scheduleService
'
);
// scheduleService 임포트
beforeAll
(
async
()
=>
{
await
sequelize
.
sync
({
force
:
true
});
...
...
@@ -62,6 +62,7 @@ describe('Schedule Service', () => {
const
schedule
=
await
scheduleService
.
createSchedule
(
scheduleData
);
expect
(
schedule
).
toBeDefined
();
expect
(
schedule
.
user_id
).
toBe
(
2
);
expect
(
schedule
.
title
).
toBe
(
'
Bob
\'
s Fixed Schedule
'
);
...
...
@@ -158,7 +159,7 @@ describe('Schedule Service', () => {
test
(
'
should delete an existing schedule successfully
'
,
async
()
=>
{
const
result
=
await
scheduleService
.
deleteSchedule
(
2
,
1
);
expect
(
result
).
to
Be
(
true
);
expect
(
result
).
to
Equal
({
message
:
'
Schedule successfully deleted
'
}
);
// 삭제된 스케줄이 실제로 삭제되었는지 확인
const
schedule
=
await
Schedule
.
findByPk
(
2
);
...
...
@@ -192,23 +193,29 @@ describe('Schedule Service', () => {
await
expect
(
scheduleService
.
getScheduleById
(
999
,
1
)).
rejects
.
toThrow
(
'
Schedule not found
'
);
});
});
// test/schedule.test.js
describe
(
'
cleanExpiredSchedules
'
,
()
=>
{
test
(
'
should delete expired flexible schedules
'
,
async
()
=>
{
// 현재 날짜를 기준으로 만료된 스케줄과 만료되지 않은 스케줄 생성
const
now
=
new
Date
(
'
2024-05-07T00:00:00Z
'
);
// 테스트를 위한 고정된 현재 날짜
// Jest의 Fake Timers를 사용하여 Date를 고정
jest
.
useFakeTimers
(
'
modern
'
);
jest
.
setSystemTime
(
now
);
// 만료된 유동 스케줄 생성
await
Schedule
.
create
({
id
:
3
,
user_id
:
1
,
title
:
'
Expired Flexible Schedule
'
,
start_time
:
new
Date
(
'
2024-04-25T10:00:00Z
'
),
end_time
:
new
Date
(
'
2024-04-25T11:00:00Z
'
),
is_fixed
:
false
,
expiry_date
:
new
Date
(
'
2024-0
4-30
T00:00:00Z
'
),
// 이미 만료됨
expiry_date
:
new
Date
(
'
2024-0
5-06
T00:00:00Z
'
),
// 이미 만료됨
});
// 만료되지 않은 유동 스케줄 생성
await
Schedule
.
create
({
id
:
4
,
user_id
:
1
,
title
:
'
Valid Flexible Schedule
'
,
start_time
:
new
Date
(
'
2024-05-07T10:00:00Z
'
),
...
...
@@ -221,13 +228,17 @@ describe('Schedule Service', () => {
await
scheduleService
.
cleanExpiredSchedules
();
// 만료된 스케줄이 삭제되었는지 확인
const
expiredSchedule
=
await
Schedule
.
find
ByPk
(
3
);
const
expiredSchedule
=
await
Schedule
.
find
One
({
where
:
{
title
:
'
Expired Flexible Schedule
'
}
}
);
expect
(
expiredSchedule
).
toBeNull
();
// 만료되지 않은 스케줄은 남아있는지 확인
const
validSchedule
=
await
Schedule
.
find
ByPk
(
4
);
const
validSchedule
=
await
Schedule
.
find
One
({
where
:
{
title
:
'
Valid Flexible Schedule
'
}
}
);
expect
(
validSchedule
).
toBeDefined
();
expect
(
validSchedule
.
title
).
toBe
(
'
Valid Flexible Schedule
'
);
// Jest의 Fake Timers를 복구
jest
.
useRealTimers
();
});
});
});
This diff is collapsed.
Click to expand it.
services/scheduleService.js
+
242
−
222
View file @
490d41b6
...
...
@@ -5,7 +5,6 @@ const Schedule = require('../models/Schedule');
const
ScheduleResponseDTO
=
require
(
'
../dtos/ScheduleResponseDTO
'
);
class
scheduleService
{
/**
* 트랜잭션 래퍼 함수
*/
...
...
@@ -31,9 +30,9 @@ class scheduleService {
{
is_fixed
:
true
},
{
is_fixed
:
false
,
expiry_date
:
{
[
Op
.
gt
]:
new
Date
()
}
}
]
expiry_date
:
{
[
Op
.
gt
]:
new
Date
()
}
,
}
,
]
,
};
if
(
id
)
{
...
...
@@ -45,10 +44,11 @@ class scheduleService {
/**
* 스케줄 유효성 검사
* 이미 컨트롤러에서 검증했으므로, 추가 검증 필요 시 수행
*/
validateScheduleTime
(
start_time
,
end_time
)
{
if
(
new
Date
(
start_time
)
>=
new
Date
(
end_time
))
{
throw
new
Error
(
'
Start time must be before end time
'
);
throw
new
Error
(
"
Start time must be before end time
"
);
}
}
...
...
@@ -57,12 +57,20 @@ class scheduleService {
*/
getNextMonday
(
startTime
)
{
const
date
=
new
Date
(
startTime
);
const
day
=
date
.
getDay
();
const
daysUntilNextMonday
=
(
7
-
day
+
1
)
%
7
;
const
nextMonday
=
new
Date
(
date
);
nextMonday
.
setDate
(
date
.
getDate
()
+
daysUntilNextMonday
);
nextMonday
.
setHours
(
0
,
0
,
0
,
0
);
// 자정으로 설정
const
day
=
date
.
getUTCDay
();
// 0=Sunday, 1=Monday, ..., 6=Saturday
const
daysUntilNextMonday
=
(
8
-
day
)
%
7
||
7
;
// Ensure next Monday
const
nextMonday
=
new
Date
(
Date
.
UTC
(
date
.
getUTCFullYear
(),
date
.
getUTCMonth
(),
date
.
getUTCDate
()
+
daysUntilNextMonday
,
0
,
0
,
0
,
0
// Set to midnight UTC
)
);
return
nextMonday
;
}
...
...
@@ -73,9 +81,14 @@ class scheduleService {
async
createSchedule
({
userId
,
title
,
start_time
,
end_time
,
is_fixed
})
{
const
schedule
=
await
this
.
withTransaction
(
async
(
transaction
)
=>
{
this
.
validateScheduleTime
(
start_time
,
end_time
);
const
overlap
=
await
this
.
checkScheduleOverlap
(
userId
,
start_time
,
end_time
);
const
overlap
=
await
this
.
checkScheduleOverlap
(
userId
,
start_time
,
end_time
);
if
(
overlap
)
{
throw
new
Error
(
'
Schedule overlaps with existing schedule
'
);
throw
new
Error
(
"
Schedule overlaps with existing schedule
"
);
}
const
scheduleData
=
{
...
...
@@ -84,7 +97,7 @@ class scheduleService {
start_time
,
end_time
,
is_fixed
,
expiry_date
:
is_fixed
?
null
:
this
.
getNextMonday
(
start_time
)
expiry_date
:
is_fixed
?
null
:
this
.
getNextMonday
(
start_time
)
,
};
return
Schedule
.
create
(
scheduleData
,
{
transaction
});
...
...
@@ -100,30 +113,35 @@ class scheduleService {
const
updatedSchedule
=
await
this
.
withTransaction
(
async
(
transaction
)
=>
{
const
schedule
=
await
Schedule
.
findOne
({
where
:
{
id
,
user_id
:
userId
},
transaction
transaction
,
});
if
(
!
schedule
)
{
throw
new
Error
(
'
Schedule not found
'
);
throw
new
Error
(
"
Schedule not found
"
);
}
// 이미 컨트롤러에서 검증했으므로, 추가 검증이 필요하다면 수행
if
(
updateData
.
start_time
&&
updateData
.
end_time
)
{
this
.
validateScheduleTime
(
updateData
.
start_time
,
updateData
.
end_time
);
}
const
overlap
=
await
this
.
checkScheduleOverlap
(
userId
,
updateData
.
start_time
,
updateData
.
end_time
,
updateData
.
start_time
||
schedule
.
start_time
,
updateData
.
end_time
||
schedule
.
end_time
,
id
);
if
(
overlap
)
{
throw
new
Error
(
'
Schedule overlaps with existing schedule
'
);
throw
new
Error
(
"
Schedule overlaps with existing schedule
"
);
}
const
is_fixed
=
schedule
.
is_fixed
;
const
updatedDataWithExpiry
=
{
...
updateData
,
expiry_date
:
is_fixed
?
null
:
this
.
getNextMonday
(
updateData
.
start_time
),
updatedAt
:
new
Date
()
expiry_date
:
is_fixed
?
null
:
this
.
getNextMonday
(
updateData
.
start_time
||
schedule
.
start_time
),
updatedAt
:
new
Date
(),
};
delete
updatedDataWithExpiry
.
is_fixed
;
...
...
@@ -140,15 +158,15 @@ class scheduleService {
return
this
.
withTransaction
(
async
(
transaction
)
=>
{
const
result
=
await
Schedule
.
destroy
({
where
:
{
id
,
user_id
:
userId
},
transaction
transaction
,
});
if
(
!
result
)
{
throw
new
Error
(
'
Schedule not found
'
);
throw
new
Error
(
"
Schedule not found
"
);
}
// 삭제 성공 메시지 반환
return
{
message
:
'
Schedule successfully deleted
'
};
return
{
message
:
"
Schedule successfully deleted
"
};
});
}
...
...
@@ -159,9 +177,11 @@ class scheduleService {
try
{
const
schedules
=
await
Schedule
.
findAll
({
where
:
this
.
getScheduleWhereClause
(
userId
),
order
:
[[
'
start_time
'
,
'
ASC
'
]]
order
:
[[
"
start_time
"
,
"
ASC
"
]]
,
});
const
schedulesDTO
=
schedules
.
map
(
schedule
=>
new
ScheduleResponseDTO
(
schedule
));
const
schedulesDTO
=
schedules
.
map
(
(
schedule
)
=>
new
ScheduleResponseDTO
(
schedule
)
);
return
schedulesDTO
;
}
catch
(
error
)
{
throw
new
Error
(
`Failed to fetch schedules:
${
error
.
message
}
`
);
...
...
@@ -174,11 +194,11 @@ class scheduleService {
async
getScheduleById
(
id
,
userId
)
{
try
{
const
schedule
=
await
Schedule
.
findOne
({
where
:
this
.
getScheduleWhereClause
(
userId
,
id
)
where
:
this
.
getScheduleWhereClause
(
userId
,
id
)
,
});
if
(
!
schedule
)
{
throw
new
Error
(
'
Schedule not found
'
);
throw
new
Error
(
"
Schedule not found
"
);
}
return
new
ScheduleResponseDTO
(
schedule
);
...
...
@@ -195,8 +215,8 @@ class scheduleService {
await
Schedule
.
destroy
({
where
:
{
is_fixed
:
false
,
expiry_date
:
{
[
Op
.
lte
]:
new
Date
()
}
}
expiry_date
:
{
[
Op
.
lte
]:
new
Date
()
}
,
}
,
});
}
catch
(
error
)
{
throw
new
Error
(
`Failed to clean expired schedules:
${
error
.
message
}
`
);
...
...
@@ -214,16 +234,16 @@ class scheduleService {
{
[
Op
.
and
]:
[
{
start_time
:
{
[
Op
.
lte
]:
start_time
}
},
{
end_time
:
{
[
Op
.
gte
]:
start_time
}
}
]
{
end_time
:
{
[
Op
.
gte
]:
start_time
}
}
,
]
,
},
{
[
Op
.
and
]:
[
{
start_time
:
{
[
Op
.
gte
]:
start_time
}
},
{
start_time
:
{
[
Op
.
lte
]:
end_time
}
}
]
}
]
{
start_time
:
{
[
Op
.
lte
]:
end_time
}
}
,
]
,
}
,
]
,
};
if
(
excludeId
)
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment