opensoma 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/client.d.ts +3 -3
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +37 -5
- package/dist/src/client.js.map +1 -1
- package/dist/src/commands/auth.d.ts +1 -1
- package/dist/src/commands/auth.d.ts.map +1 -1
- package/dist/src/commands/auth.js +94 -52
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/mentoring.d.ts.map +1 -1
- package/dist/src/commands/mentoring.js +26 -20
- package/dist/src/commands/mentoring.js.map +1 -1
- package/dist/src/commands/room.d.ts.map +1 -1
- package/dist/src/commands/room.js +25 -2
- package/dist/src/commands/room.js.map +1 -1
- package/dist/src/constants.d.ts +52 -9
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +65 -9
- package/dist/src/constants.js.map +1 -1
- package/dist/src/formatters.d.ts.map +1 -1
- package/dist/src/formatters.js +79 -39
- package/dist/src/formatters.js.map +1 -1
- package/dist/src/http.d.ts +3 -0
- package/dist/src/http.d.ts.map +1 -1
- package/dist/src/http.js +42 -1
- package/dist/src/http.js.map +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/shared/utils/html.d.ts +3 -0
- package/dist/src/shared/utils/html.d.ts.map +1 -0
- package/dist/src/shared/utils/html.js +12 -0
- package/dist/src/shared/utils/html.js.map +1 -0
- package/dist/src/shared/utils/swmaestro.d.ts +2 -0
- package/dist/src/shared/utils/swmaestro.d.ts.map +1 -1
- package/dist/src/shared/utils/swmaestro.js +28 -5
- package/dist/src/shared/utils/swmaestro.js.map +1 -1
- package/dist/src/shared/utils/toz.d.ts +23 -0
- package/dist/src/shared/utils/toz.d.ts.map +1 -0
- package/dist/src/shared/utils/toz.js +72 -0
- package/dist/src/shared/utils/toz.js.map +1 -0
- package/dist/src/token-extractor.d.ts +9 -1
- package/dist/src/token-extractor.d.ts.map +1 -1
- package/dist/src/token-extractor.js +54 -10
- package/dist/src/token-extractor.js.map +1 -1
- package/dist/src/toz-formatters.d.ts +9 -0
- package/dist/src/toz-formatters.d.ts.map +1 -0
- package/dist/src/toz-formatters.js +151 -0
- package/dist/src/toz-formatters.js.map +1 -0
- package/dist/src/toz-http.d.ts +27 -0
- package/dist/src/toz-http.d.ts.map +1 -0
- package/dist/src/toz-http.js +154 -0
- package/dist/src/toz-http.js.map +1 -0
- package/dist/src/types.d.ts +88 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +65 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +1 -1
- package/src/__fixtures__/toz/toz_all_branches.json +211 -0
- package/src/__fixtures__/toz/toz_booking.html +2190 -0
- package/src/__fixtures__/toz/toz_boothes.json +59 -0
- package/src/__fixtures__/toz/toz_duration.json +25 -0
- package/src/__fixtures__/toz/toz_mypage_response.html +388 -0
- package/src/__fixtures__/toz/toz_page.html +211 -0
- package/src/client.test.ts +63 -16
- package/src/client.ts +43 -6
- package/src/commands/auth.ts +107 -50
- package/src/commands/mentoring.ts +34 -26
- package/src/commands/room.ts +31 -3
- package/src/constants.ts +74 -9
- package/src/formatters.test.ts +6 -2
- package/src/formatters.ts +92 -45
- package/src/http.test.ts +215 -0
- package/src/http.ts +45 -1
- package/src/index.ts +3 -0
- package/src/shared/utils/html.ts +12 -0
- package/src/shared/utils/swmaestro.test.ts +44 -0
- package/src/shared/utils/swmaestro.ts +30 -5
- package/src/shared/utils/toz.test.ts +133 -0
- package/src/shared/utils/toz.ts +100 -0
- package/src/token-extractor.test.ts +30 -5
- package/src/token-extractor.ts +65 -13
- package/src/toz-formatters.test.ts +197 -0
- package/src/toz-formatters.ts +211 -0
- package/src/toz-http.test.ts +157 -0
- package/src/toz-http.ts +188 -0
- package/src/types.test.ts +4 -1
- package/src/types.ts +81 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
5
|
+
<title>토즈</title>
|
|
6
|
+
|
|
7
|
+
<script type="text/javascript" src="/js/jquery-1.4.4.min.js"></script>
|
|
8
|
+
<script type="text/javascript" src="/js/jquery-ui-1.8.9.custom.min.js"></script>
|
|
9
|
+
<script type="text/javascript" src="/js/jquery.ui.datepicker-ko.js"></script>
|
|
10
|
+
<link type="text/css" href="/css/blitzer/jquery-ui-1.8.13.custom.css" rel="stylesheet" />
|
|
11
|
+
<link type="text/css" href="/css/partnerReservation.css" rel="stylesheet" />
|
|
12
|
+
<style>
|
|
13
|
+
.header {
|
|
14
|
+
background: #2c2c2c;
|
|
15
|
+
height: 80px;
|
|
16
|
+
border-bottom: 5px solid #ccc;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.header .logo {
|
|
20
|
+
position: relative;
|
|
21
|
+
width: 950px;
|
|
22
|
+
margin: 0 auto;
|
|
23
|
+
padding: 40px 0 0 0;
|
|
24
|
+
height: 40px;
|
|
25
|
+
}
|
|
26
|
+
.header .partner_logo {
|
|
27
|
+
color: white;
|
|
28
|
+
font-weight: bold;
|
|
29
|
+
font-size: 17px;
|
|
30
|
+
letter-spacing: -1px;
|
|
31
|
+
position: absolute;
|
|
32
|
+
top: 0;
|
|
33
|
+
right: 0;
|
|
34
|
+
padding: 50px 0 0 0;
|
|
35
|
+
height: 40px;
|
|
36
|
+
}
|
|
37
|
+
ul.btn-list {
|
|
38
|
+
position: relative;
|
|
39
|
+
list-style: none;
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: 0;
|
|
42
|
+
height: 100%;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
ul.btn-list li {
|
|
46
|
+
position: relative;
|
|
47
|
+
margin: 0;
|
|
48
|
+
text-align: left;
|
|
49
|
+
width: 100%;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
ul.btn-list li.btn-list-1 {
|
|
53
|
+
padding: 42px 0px;
|
|
54
|
+
}
|
|
55
|
+
ul.btn-list li.btn-list-3 {
|
|
56
|
+
padding: 42px 0px;
|
|
57
|
+
}
|
|
58
|
+
ul.btn-list li.btn-list-4 {
|
|
59
|
+
padding: 49px 0px;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
62
|
+
</head>
|
|
63
|
+
<body>
|
|
64
|
+
<!-- top -->
|
|
65
|
+
<div class="header" style="padding-bottom: 6px">
|
|
66
|
+
<div class="logo" style="padding-bottom: 6px">
|
|
67
|
+
<div>
|
|
68
|
+
<a href="/partner/reservation/fkii3/swmaestro/index.htm?key=&projectSeq=&addedInfo=&tozApplyType="
|
|
69
|
+
><img src="/images/partner/toz_logo.png"
|
|
70
|
+
/></a>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="partner_logo">
|
|
73
|
+
기업전용 문의접수: <a href="mailto: b2bsb@toz.co.kr" style="color: white">b2bsb@toz.co.kr</a>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div style="display: flex; flex-direction: row; justify-content: center; margin: -5px 0 0 0">
|
|
78
|
+
<div
|
|
79
|
+
class="layoutBody"
|
|
80
|
+
style="
|
|
81
|
+
position: relative;
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
justify-content: center;
|
|
85
|
+
border-top: 5px solid #b00e33;
|
|
86
|
+
"
|
|
87
|
+
>
|
|
88
|
+
<div style="display: flex; flex-direction: row; width: 950px; border-bottom: 2px solid #d03f5f">
|
|
89
|
+
<div style="position: relative; width: 700px; z-index: 1">
|
|
90
|
+
<div style="padding-left: 30px; width: 380px; word-break: keep-all">
|
|
91
|
+
<p style="font-weight: bold; color: #890624; font-size: 18px; margin: 20px 0 10px 0">
|
|
92
|
+
(필독) 외부 회의실 예약 및 이용시 주의사항
|
|
93
|
+
</p>
|
|
94
|
+
<p></p>
|
|
95
|
+
<p style="font-size: 13px; color: #939393; font-weight: bold; line-height: 25px">
|
|
96
|
+
· 최소 2시간 부터 사용 가능하며 최대 3시간까지 사용합니다.<br />
|
|
97
|
+
· 예약 후 멘토링/특강 일정 변경시 반드시 예약 취소합니다.<br />
|
|
98
|
+
· 본인의 예약 미취소로 인해 발생한 비용은 개인에게<br />
|
|
99
|
+
<span style="display: inline-block; padding-left: 10px">직접 청구 될 수 있습니다.</span><br />
|
|
100
|
+
· 이용자(연수생/엑스퍼트/멘토) 경고에 해당하는 경우<br />
|
|
101
|
+
<span style="display: inline-block; padding-left: 14px">(1) 예약 후 예약 취소 없이 일방적인 노쇼</span
|
|
102
|
+
><br />
|
|
103
|
+
<span style="display: inline-block; padding-left: 14px"
|
|
104
|
+
>(2) 멘토-연수생, 엑스퍼트-연수생과의 활동이 아닌</span
|
|
105
|
+
><br />
|
|
106
|
+
<span style="display: inline-block; padding-left: 36px">목적 외 활동을 한 경우</span><br />
|
|
107
|
+
<span style="display: inline-block; padding-left: 14px">(3) 기타 부적합한 용도로 사용한 경우</span>
|
|
108
|
+
</p>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div style="position: absolute; bottom: 10px; left: 40px">
|
|
112
|
+
<div class="companyName" style="padding: 5px 0">
|
|
113
|
+
<span style="font-weight: bold; color: #2c2c2c; border-bottom: 1px solid #939393; padding-bottom: 2px"
|
|
114
|
+
>AI‧SW마에스트로</span
|
|
115
|
+
>
|
|
116
|
+
</div>
|
|
117
|
+
<div
|
|
118
|
+
class="text"
|
|
119
|
+
style="padding: 5px 0; font-size: 14px; font-weight: bold; color: #939393; letter-spacing: -1px"
|
|
120
|
+
>
|
|
121
|
+
제휴내용은
|
|
122
|
+
</div>
|
|
123
|
+
<div style="padding: 5px 0">
|
|
124
|
+
<span class="desc" style="color: #890624; border-bottom: 1px solid #939393; padding-bottom: 2px"
|
|
125
|
+
>20% 할인</span
|
|
126
|
+
><span class="text"> 입니다.</span>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
<div style="position: relative; width: 250px; height: 388px">
|
|
131
|
+
<img src="/images/partner/deco_toz_main_1.png" style="position: absolute; bottom: 0px; right: 250px" />
|
|
132
|
+
<ul class="btn-list">
|
|
133
|
+
<li class="btn-list-1" style="background: #890624">
|
|
134
|
+
<a href="/partner/reservation/fkii3/swmaestro/booking.htm?key=&projectSeq=&addedInfo=&tozApplyType="
|
|
135
|
+
><img alt="예약하기" src="/images/partner/btn_toz_main_1.png" style="margin-left: 30px"
|
|
136
|
+
/></a>
|
|
137
|
+
</li>
|
|
138
|
+
|
|
139
|
+
<li class="btn-list-3" style="background: #c42649">
|
|
140
|
+
<a href="/partner/reservation/fkii3/swmaestro/startmypage.htm?key=&projectSeq=&addedInfo=&tozApplyType="
|
|
141
|
+
><img alt="예약확인하기" src="/images/partner/btn_toz_main_3.png" style="margin-left: 30px"
|
|
142
|
+
/></a>
|
|
143
|
+
</li>
|
|
144
|
+
<li class="btn-list-4" style="background: #d03f5f">
|
|
145
|
+
<a href="https://work.toz.co.kr/branchSearch?page=1&onesBranchType=TMC" target="_blank"
|
|
146
|
+
><img alt="토즈모임센터 지점안내" src="/images/partner/btn_toz_main_4.png" style="margin-left: 30px"
|
|
147
|
+
/></a>
|
|
148
|
+
</li>
|
|
149
|
+
</ul>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<div
|
|
154
|
+
style="
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-direction: row;
|
|
157
|
+
justify-content: center;
|
|
158
|
+
position: relative;
|
|
159
|
+
width: 950px;
|
|
160
|
+
margin: 0 auto;
|
|
161
|
+
text-align: center;
|
|
162
|
+
border-bottom: 2px solid #d03f5f;
|
|
163
|
+
"
|
|
164
|
+
>
|
|
165
|
+
<img src="/images/partner/btn_link_map.png" usemap="#map_link" style="width: 808px; height: 168px" />
|
|
166
|
+
<map name="map_link">
|
|
167
|
+
<area
|
|
168
|
+
shape="rect"
|
|
169
|
+
coords="10,30,210,160"
|
|
170
|
+
href="https://moim.toz.co.kr"
|
|
171
|
+
title="토즈 서비스 그룹"
|
|
172
|
+
target="_blank"
|
|
173
|
+
/>
|
|
174
|
+
<area
|
|
175
|
+
shape="rect"
|
|
176
|
+
coords="280,30,510,160"
|
|
177
|
+
href="https://moim.toz.co.kr/customerCenter/posts/all"
|
|
178
|
+
title="토즈 고객센터"
|
|
179
|
+
target="_blank"
|
|
180
|
+
/>
|
|
181
|
+
<area
|
|
182
|
+
shape="rect"
|
|
183
|
+
coords="570,25,810,160"
|
|
184
|
+
href="https://moim.toz.co.kr/customerCenter/posts/event"
|
|
185
|
+
title="토즈 이벤트"
|
|
186
|
+
target="_blank"
|
|
187
|
+
/>
|
|
188
|
+
</map>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<!-- google analytics for (http)partner.toz.co.kr -->
|
|
194
|
+
<script type="text/javascript">
|
|
195
|
+
var _gaq = _gaq || []
|
|
196
|
+
_gaq.push(['_setAccount', 'UA-23075111-3'])
|
|
197
|
+
_gaq.push(['_trackPageview'])
|
|
198
|
+
|
|
199
|
+
;(function () {
|
|
200
|
+
var ga = document.createElement('script')
|
|
201
|
+
ga.type = 'text/javascript'
|
|
202
|
+
ga.async = true
|
|
203
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'
|
|
204
|
+
var s = document.getElementsByTagName('script')[0]
|
|
205
|
+
s.parentNode.insertBefore(ga, s)
|
|
206
|
+
})()
|
|
207
|
+
</script>
|
|
208
|
+
<!-- // google analytics for (http)partner.toz.co.kr -->
|
|
209
|
+
<!-- // bottom -->
|
|
210
|
+
</body>
|
|
211
|
+
</html>
|
package/src/client.test.ts
CHANGED
|
@@ -72,14 +72,19 @@ describe('SomaClient', () => {
|
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
test('mutating operations post expected payloads', async () => {
|
|
75
|
+
const mentoringDetailHtml =
|
|
76
|
+
'<div class="group"><strong class="t">모집 명</strong><div class="c">[자유 멘토링] 기존 멘토링</div></div><div class="group"><strong class="t">접수 기간</strong><div class="c">2026.03.01 ~ 2026.03.15</div></div><div class="group"><strong class="t">강의날짜</strong><div class="c"><span>2026.03.20 10:00시 ~ 12:00시</span></div></div><div class="group"><strong class="t">장소</strong><div class="c">온라인(Webex)</div></div><div class="group"><strong class="t">모집인원</strong><div class="c">5명</div></div><div class="group"><strong class="t">작성자</strong><div class="c">전수열</div></div><div class="group"><strong class="t">등록일</strong><div class="c">2026.03.01</div></div><div class="cont"><p>기존 내용</p></div>'
|
|
75
77
|
const client = new SomaClient()
|
|
76
|
-
const calls: Array<{ path: string; data: Record<string, string> }> = []
|
|
78
|
+
const calls: Array<{ method: string; path: string; data: Record<string, string> }> = []
|
|
79
|
+
const captor = (method: string) => async (path: string, data: Record<string, string>) => {
|
|
80
|
+
calls.push({ method, path, data })
|
|
81
|
+
return ''
|
|
82
|
+
}
|
|
77
83
|
Reflect.set(client, 'http', {
|
|
78
84
|
checkLogin: async () => ({ userId: 'user@example.com', userNm: 'Test' }),
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
},
|
|
85
|
+
get: async () => mentoringDetailHtml,
|
|
86
|
+
post: captor('post'),
|
|
87
|
+
postForm: captor('postForm'),
|
|
83
88
|
})
|
|
84
89
|
|
|
85
90
|
await client.mentoring.create({
|
|
@@ -110,14 +115,14 @@ describe('SomaClient', () => {
|
|
|
110
115
|
})
|
|
111
116
|
await client.event.apply(11)
|
|
112
117
|
|
|
113
|
-
expect(calls.map((call) => call.path)).toEqual([
|
|
114
|
-
'
|
|
115
|
-
'
|
|
116
|
-
'
|
|
117
|
-
'
|
|
118
|
-
'
|
|
119
|
-
'
|
|
120
|
-
'
|
|
118
|
+
expect(calls.map((call) => `${call.method}:${call.path}`)).toEqual([
|
|
119
|
+
'postForm:/mypage/mentoLec/insert.do',
|
|
120
|
+
'postForm:/mypage/mentoLec/update.do',
|
|
121
|
+
'post:/mypage/mentoLec/delete.do',
|
|
122
|
+
'post:/application/application/application.do',
|
|
123
|
+
'post:/mypage/userAnswer/cancel.do',
|
|
124
|
+
'post:/mypage/itemRent/insert.do',
|
|
125
|
+
'post:/application/application/application.do',
|
|
121
126
|
])
|
|
122
127
|
expect(calls[0]?.data).toMatchObject({
|
|
123
128
|
menuNo: MENU_NO.MENTORING,
|
|
@@ -161,6 +166,38 @@ describe('SomaClient', () => {
|
|
|
161
166
|
})
|
|
162
167
|
})
|
|
163
168
|
|
|
169
|
+
test('mentoring.update merges partial params with existing data', async () => {
|
|
170
|
+
const mentoringDetailHtml =
|
|
171
|
+
'<div class="group"><strong class="t">모집 명</strong><div class="c">[멘토 특강] 웹 성능 특강</div></div><div class="group"><strong class="t">접수 기간</strong><div class="c">2026.04.01 ~ 2026.04.10</div></div><div class="group"><strong class="t">강의날짜</strong><div class="c"><span>2026.04.11 14:00시 ~ 15:30시</span></div></div><div class="group"><strong class="t">장소</strong><div class="c">온라인(Webex)</div></div><div class="group"><strong class="t">모집인원</strong><div class="c">20명</div></div><div class="group"><strong class="t">작성자</strong><div class="c">전수열</div></div><div class="group"><strong class="t">등록일</strong><div class="c">2026.04.01</div></div><div class="cont"><p>세션 본문</p></div>'
|
|
172
|
+
const client = new SomaClient()
|
|
173
|
+
const postFormCalls: Array<{ path: string; data: Record<string, string> }> = []
|
|
174
|
+
Reflect.set(client, 'http', {
|
|
175
|
+
checkLogin: async () => ({ userId: 'user@example.com', userNm: 'Test' }),
|
|
176
|
+
get: async () => mentoringDetailHtml,
|
|
177
|
+
postForm: async (path: string, data: Record<string, string>) => {
|
|
178
|
+
postFormCalls.push({ path, data })
|
|
179
|
+
return ''
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
await client.mentoring.update(9572, { title: '변경된 제목' })
|
|
184
|
+
|
|
185
|
+
expect(postFormCalls).toHaveLength(1)
|
|
186
|
+
expect(postFormCalls[0]?.data).toMatchObject({
|
|
187
|
+
qustnrSj: '변경된 제목',
|
|
188
|
+
qustnrSn: '9572',
|
|
189
|
+
reportCd: 'MRC020',
|
|
190
|
+
eventDt: '2026-04-11',
|
|
191
|
+
eventStime: '14:00',
|
|
192
|
+
eventEtime: '15:30',
|
|
193
|
+
place: '온라인(Webex)',
|
|
194
|
+
applyCnt: '20',
|
|
195
|
+
bgnde: '2026-04-01',
|
|
196
|
+
endde: '2026-04-10',
|
|
197
|
+
qestnarCn: '<p>세션 본문</p>',
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
|
|
164
201
|
test('room, dashboard, notice, team, member, event, and history routes use expected endpoints', async () => {
|
|
165
202
|
const client = new SomaClient()
|
|
166
203
|
const calls: Array<{ method: string; path: string; data: Record<string, string> | undefined }> = []
|
|
@@ -197,13 +234,13 @@ describe('SomaClient', () => {
|
|
|
197
234
|
post: async (path: string, data: Record<string, string>) => {
|
|
198
235
|
calls.push({ method: 'post', path, data })
|
|
199
236
|
if (path === '/mypage/officeMng/rentTime.do') {
|
|
200
|
-
return '<
|
|
237
|
+
return '<span class="ck-st2 disabled" data-hour="09" data-minute="00"><input type="checkbox" disabled="disabled"><label title="아침 회의<br>예약자 : 김오픈">오전 09:00</label></span>'
|
|
201
238
|
}
|
|
202
239
|
return '<ul class="bbs-reserve"><li class="item"><a href="javascript:void(0);" onclick="location.href=\'/sw/mypage/officeMng/view.do?itemId=17\';"><div class="cont"><h4 class="tit">스페이스 A1</h4><ul class="txt bul-dot grey"><li>이용기간 : 2026-04-01 ~ 2026-12-31</li><li><p>설명 : 4인</p></li><li class="time-list"><div class="time-grid"><span>09:00</span></div></li></ul></div></a></li></ul>'
|
|
203
240
|
},
|
|
204
241
|
})
|
|
205
242
|
|
|
206
|
-
const roomList = await client.room.list({ date: '2026-04-01', room: 'A1' })
|
|
243
|
+
const roomList = await client.room.list({ date: '2026-04-01', room: 'A1', includeReservations: true })
|
|
207
244
|
const roomSlots = await client.room.available(17, '2026-04-01')
|
|
208
245
|
const dashboard = await client.dashboard.get()
|
|
209
246
|
const noticeList = await client.notice.list({ page: 2 })
|
|
@@ -215,7 +252,12 @@ describe('SomaClient', () => {
|
|
|
215
252
|
const history = await client.mentoring.history({ page: 4 })
|
|
216
253
|
|
|
217
254
|
expect(roomList[0]?.itemId).toBe(17)
|
|
218
|
-
expect(
|
|
255
|
+
expect(roomList[0]?.timeSlots).toEqual([
|
|
256
|
+
{ time: '09:00', available: false, reservation: { title: '아침 회의', bookedBy: '김오픈' } },
|
|
257
|
+
])
|
|
258
|
+
expect(roomSlots).toEqual([
|
|
259
|
+
{ time: '09:00', available: false, reservation: { title: '아침 회의', bookedBy: '김오픈' } },
|
|
260
|
+
])
|
|
219
261
|
expect(dashboard.name).toBe('전수열')
|
|
220
262
|
expect(dashboard.mentoringSessions).toEqual([
|
|
221
263
|
{
|
|
@@ -249,6 +291,11 @@ describe('SomaClient', () => {
|
|
|
249
291
|
|
|
250
292
|
const dashboardCallIndex = calls.findIndex((c) => c.path === '/mypage/myMain/dashboard.do')
|
|
251
293
|
expect(dashboardCallIndex).toBeGreaterThanOrEqual(0)
|
|
294
|
+
expect(calls).toContainEqual({
|
|
295
|
+
method: 'post',
|
|
296
|
+
path: '/mypage/officeMng/rentTime.do',
|
|
297
|
+
data: { viewType: 'CONTBODY', itemId: '17', rentDt: '2026-04-01' },
|
|
298
|
+
})
|
|
252
299
|
const mentoringListCall = calls.find((c) => c.path === '/mypage/mentoLec/list.do')
|
|
253
300
|
expect(mentoringListCall?.data).toEqual({
|
|
254
301
|
menuNo: MENU_NO.MENTORING,
|
package/src/client.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
buildUpdateMentoringPayload,
|
|
17
17
|
parseEventDetail,
|
|
18
18
|
resolveRoomId,
|
|
19
|
+
toMentoringType,
|
|
19
20
|
toRegionCode,
|
|
20
21
|
toReportTypeCd,
|
|
21
22
|
} from './shared/utils/swmaestro'
|
|
@@ -27,6 +28,7 @@ import type {
|
|
|
27
28
|
MemberInfo,
|
|
28
29
|
MentoringDetail,
|
|
29
30
|
MentoringListItem,
|
|
31
|
+
MentoringUpdateOptions,
|
|
30
32
|
NoticeDetail,
|
|
31
33
|
NoticeListItem,
|
|
32
34
|
Pagination,
|
|
@@ -71,7 +73,7 @@ export class SomaClient {
|
|
|
71
73
|
regEnd?: string
|
|
72
74
|
content?: string
|
|
73
75
|
}): Promise<void>
|
|
74
|
-
update(id: number, params:
|
|
76
|
+
update(id: number, params: MentoringUpdateOptions): Promise<void>
|
|
75
77
|
delete(id: number): Promise<void>
|
|
76
78
|
apply(id: number): Promise<void>
|
|
77
79
|
cancel(params: { applySn: number; qustnrSn: number }): Promise<void>
|
|
@@ -79,7 +81,7 @@ export class SomaClient {
|
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
readonly room: {
|
|
82
|
-
list(options?: { date?: string; room?: string }): Promise<RoomCard[]>
|
|
84
|
+
list(options?: { date?: string; room?: string; includeReservations?: boolean }): Promise<RoomCard[]>
|
|
83
85
|
available(roomId: number, date: string): Promise<RoomCard['timeSlots']>
|
|
84
86
|
reserve(params: {
|
|
85
87
|
roomId: number
|
|
@@ -176,14 +178,27 @@ export class SomaClient {
|
|
|
176
178
|
},
|
|
177
179
|
create: async (params) => {
|
|
178
180
|
await this.requireAuth()
|
|
179
|
-
const html = await this.http.
|
|
181
|
+
const html = await this.http.postForm('/mypage/mentoLec/insert.do', buildMentoringPayload(params))
|
|
180
182
|
if (this.containsErrorIndicator(html)) {
|
|
181
183
|
throw new Error(this.extractErrorMessage(html) || '멘토링 등록에 실패했습니다.')
|
|
182
184
|
}
|
|
183
185
|
},
|
|
184
186
|
update: async (id, params) => {
|
|
185
187
|
await this.requireAuth()
|
|
186
|
-
const
|
|
188
|
+
const existing = await this.mentoring.get(id)
|
|
189
|
+
const merged = buildUpdateMentoringPayload(id, {
|
|
190
|
+
title: params.title ?? existing.title,
|
|
191
|
+
type: params.type ?? toMentoringType(existing.type),
|
|
192
|
+
date: params.date ?? existing.sessionDate,
|
|
193
|
+
startTime: params.startTime ?? existing.sessionTime.start,
|
|
194
|
+
endTime: params.endTime ?? existing.sessionTime.end,
|
|
195
|
+
venue: params.venue ?? existing.venue,
|
|
196
|
+
maxAttendees: params.maxAttendees ?? existing.attendees.max,
|
|
197
|
+
regStart: params.regStart ?? existing.registrationPeriod.start,
|
|
198
|
+
regEnd: params.regEnd ?? existing.registrationPeriod.end,
|
|
199
|
+
content: params.content ?? existing.content,
|
|
200
|
+
})
|
|
201
|
+
const html = await this.http.postForm('/mypage/mentoLec/update.do', merged)
|
|
187
202
|
if (this.containsErrorIndicator(html)) {
|
|
188
203
|
throw new Error(this.extractErrorMessage(html) || '멘토링 수정에 실패했습니다.')
|
|
189
204
|
}
|
|
@@ -216,13 +231,35 @@ export class SomaClient {
|
|
|
216
231
|
this.room = {
|
|
217
232
|
list: async (options) => {
|
|
218
233
|
await this.requireAuth()
|
|
219
|
-
|
|
234
|
+
const date = options?.date ?? new Date().toISOString().slice(0, 10)
|
|
235
|
+
const rooms = formatters.parseRoomList(
|
|
220
236
|
await this.http.post('/mypage/officeMng/list.do', {
|
|
221
237
|
menuNo: MENU_NO.ROOM,
|
|
222
|
-
sdate:
|
|
238
|
+
sdate: date,
|
|
223
239
|
searchItemId: options?.room ? String(resolveRoomId(options.room)) : '',
|
|
224
240
|
}),
|
|
225
241
|
)
|
|
242
|
+
|
|
243
|
+
if (!options?.includeReservations) return rooms
|
|
244
|
+
|
|
245
|
+
return Promise.all(
|
|
246
|
+
rooms.map(async (room) => {
|
|
247
|
+
try {
|
|
248
|
+
const html = await this.http.post('/mypage/officeMng/rentTime.do', {
|
|
249
|
+
viewType: 'CONTBODY',
|
|
250
|
+
itemId: String(room.itemId),
|
|
251
|
+
rentDt: date,
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
...room,
|
|
256
|
+
timeSlots: formatters.parseRoomSlots(html),
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
return room
|
|
260
|
+
}
|
|
261
|
+
}),
|
|
262
|
+
)
|
|
226
263
|
},
|
|
227
264
|
available: async (roomId, date) => {
|
|
228
265
|
await this.requireAuth()
|