@things-factory/dataset 9.1.19 → 9.2.13
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-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/activities/activity-data-review.js +5 -2
- package/dist-server/activities/activity-data-review.js.map +1 -1
- package/dist-server/activities/activity-ooc-review.js +4 -1
- package/dist-server/activities/activity-ooc-review.js.map +1 -1
- package/dist-server/controllers/create-data-ooc.js +2 -1
- package/dist-server/controllers/create-data-ooc.js.map +1 -1
- package/dist-server/controllers/create-data-sample.js +2 -2
- package/dist-server/controllers/create-data-sample.js.map +1 -1
- package/dist-server/controllers/issue-data-collection-task.js +9 -5
- package/dist-server/controllers/issue-data-collection-task.js.map +1 -1
- package/dist-server/controllers/issue-ooc-resolve.js +11 -6
- package/dist-server/controllers/issue-ooc-resolve.js.map +1 -1
- package/dist-server/controllers/issue-ooc-review.js +9 -6
- package/dist-server/controllers/issue-ooc-review.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -13
- package/spec/integration/debug.spec.ts +42 -0
- package/spec/integration/ooc-lifecycle.spec.ts +484 -0
- package/spec/integration/ooc-workflow.spec.ts +276 -0
- package/spec/integration/simple.spec.ts +62 -0
- package/spec/unit/controllers/activity-callbacks.spec.ts +609 -0
- package/spec/unit/controllers/create-data-ooc.spec.ts +310 -0
- package/spec/unit/controllers/issue-ooc-resolve.spec.ts +431 -0
- package/spec/unit/controllers/issue-ooc-review.spec.ts +288 -0
- package/spec/unit/data-use-case.spec.ts +150 -0
- package/spec/unit/ooc-state-transition.spec.ts +233 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* create-data-ooc Controller Unit Tests
|
|
3
|
+
* DataOoc 생성 컨트롤러 테스트
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TestDatabase } from '../../../../../test/test-database'
|
|
7
|
+
import { withTestTransaction } from '../../../../../test/test-context'
|
|
8
|
+
import {
|
|
9
|
+
domainFactory,
|
|
10
|
+
userFactory,
|
|
11
|
+
dataSetFactory,
|
|
12
|
+
dataSampleFactory,
|
|
13
|
+
dataOocFactory
|
|
14
|
+
} from '../../../../../test/factories'
|
|
15
|
+
import { DataOocStatus } from '../../../../../test/entities/schemas'
|
|
16
|
+
|
|
17
|
+
describe('create-data-ooc Controller', () => {
|
|
18
|
+
let testDb: TestDatabase
|
|
19
|
+
|
|
20
|
+
beforeAll(async () => {
|
|
21
|
+
testDb = TestDatabase.getInstance()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('DataOoc 생성 기본 동작', () => {
|
|
25
|
+
it('DataSample에서 DataOoc 생성 시 ISSUED 상태로 생성되어야 한다', async () => {
|
|
26
|
+
await withTestTransaction(async (context) => {
|
|
27
|
+
const { tx, domain, user } = context.state
|
|
28
|
+
|
|
29
|
+
// Given: DataSet과 OOC 조건의 DataSample
|
|
30
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
31
|
+
const dataSample = await dataSampleFactory.createOocSample({}, dataSet, tx)
|
|
32
|
+
|
|
33
|
+
// When: DataOoc 생성 시뮬레이션 (createDataOoc 로직)
|
|
34
|
+
const dataOoc = await tx.save('DataOoc', {
|
|
35
|
+
...dataSample,
|
|
36
|
+
name: `OOC-${dataSet.name}-${Date.now()}`,
|
|
37
|
+
history: [
|
|
38
|
+
{
|
|
39
|
+
user: {
|
|
40
|
+
id: user.id,
|
|
41
|
+
username: user.email,
|
|
42
|
+
name: user.name
|
|
43
|
+
},
|
|
44
|
+
state: DataOocStatus.ISSUED,
|
|
45
|
+
timestamp: dataSample.collectedAt
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
state: DataOocStatus.ISSUED,
|
|
49
|
+
dataSample,
|
|
50
|
+
dataSet,
|
|
51
|
+
domain
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
// Then
|
|
55
|
+
expect(dataOoc).toBeDefined()
|
|
56
|
+
expect(dataOoc.state).toBe(DataOocStatus.ISSUED)
|
|
57
|
+
expect(dataOoc.history).toBeDefined()
|
|
58
|
+
expect(dataOoc.history.length).toBe(1)
|
|
59
|
+
expect(dataOoc.history[0].state).toBe(DataOocStatus.ISSUED)
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('DataOoc 생성 시 DataSample의 data, judgment, ooc, oos가 복사되어야 한다', async () => {
|
|
64
|
+
await withTestTransaction(async (context) => {
|
|
65
|
+
const { tx, domain, user } = context.state
|
|
66
|
+
|
|
67
|
+
// Given
|
|
68
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
69
|
+
const sampleData = { temperature: 95, humidity: 50 }
|
|
70
|
+
const sampleJudgment = {
|
|
71
|
+
temperature: { ooc: true, oos: false },
|
|
72
|
+
humidity: { ooc: false, oos: false }
|
|
73
|
+
}
|
|
74
|
+
const dataSample = await dataSampleFactory.createWithDataSet(
|
|
75
|
+
{
|
|
76
|
+
data: sampleData,
|
|
77
|
+
judgment: sampleJudgment,
|
|
78
|
+
ooc: true,
|
|
79
|
+
oos: false
|
|
80
|
+
},
|
|
81
|
+
dataSet,
|
|
82
|
+
domain,
|
|
83
|
+
tx
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
// When: DataOoc 생성 (createDataOoc 로직 시뮬레이션)
|
|
87
|
+
const dataOoc = await tx.save('DataOoc', {
|
|
88
|
+
name: `OOC-${dataSet.name}`,
|
|
89
|
+
data: dataSample.data,
|
|
90
|
+
judgment: dataSample.judgment,
|
|
91
|
+
ooc: dataSample.ooc,
|
|
92
|
+
oos: dataSample.oos,
|
|
93
|
+
collectedAt: dataSample.collectedAt,
|
|
94
|
+
workDate: dataSample.workDate,
|
|
95
|
+
workShift: dataSample.workShift,
|
|
96
|
+
history: [
|
|
97
|
+
{
|
|
98
|
+
user: { id: user.id, name: user.name },
|
|
99
|
+
state: DataOocStatus.ISSUED,
|
|
100
|
+
timestamp: dataSample.collectedAt
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
state: DataOocStatus.ISSUED,
|
|
104
|
+
dataSample,
|
|
105
|
+
dataSet,
|
|
106
|
+
domain
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Then
|
|
110
|
+
expect(dataOoc.data).toEqual(sampleData)
|
|
111
|
+
expect(dataOoc.judgment).toEqual(sampleJudgment)
|
|
112
|
+
expect(dataOoc.ooc).toBe(true)
|
|
113
|
+
expect(dataOoc.oos).toBe(false)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('DataOoc 생성 시 history의 첫 번째 엔트리는 생성자 정보를 포함해야 한다', async () => {
|
|
118
|
+
await withTestTransaction(async (context) => {
|
|
119
|
+
const { tx, domain, user } = context.state
|
|
120
|
+
|
|
121
|
+
// Given
|
|
122
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
123
|
+
const dataSample = await dataSampleFactory.createOocSample({}, dataSet, tx)
|
|
124
|
+
const collectedAt = new Date()
|
|
125
|
+
|
|
126
|
+
// When
|
|
127
|
+
const dataOoc = await tx.save('DataOoc', {
|
|
128
|
+
name: `OOC-${dataSet.name}`,
|
|
129
|
+
data: dataSample.data,
|
|
130
|
+
ooc: true,
|
|
131
|
+
collectedAt,
|
|
132
|
+
history: [
|
|
133
|
+
{
|
|
134
|
+
user: {
|
|
135
|
+
id: user.id,
|
|
136
|
+
username: user.email,
|
|
137
|
+
name: user.name
|
|
138
|
+
},
|
|
139
|
+
state: DataOocStatus.ISSUED,
|
|
140
|
+
timestamp: collectedAt
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
state: DataOocStatus.ISSUED,
|
|
144
|
+
dataSample,
|
|
145
|
+
dataSet,
|
|
146
|
+
domain
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
// Then
|
|
150
|
+
expect(dataOoc.history[0].user.id).toBe(user.id)
|
|
151
|
+
expect(dataOoc.history[0].user.name).toBe(user.name)
|
|
152
|
+
expect(dataOoc.history[0].state).toBe(DataOocStatus.ISSUED)
|
|
153
|
+
expect(dataOoc.history[0].timestamp).toEqual(collectedAt)
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('DataOoc와 DataSample의 관계가 올바르게 설정되어야 한다', async () => {
|
|
158
|
+
await withTestTransaction(async (context) => {
|
|
159
|
+
const { tx, domain } = context.state
|
|
160
|
+
|
|
161
|
+
// Given
|
|
162
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
163
|
+
const dataSample = await dataSampleFactory.createOocSample({}, dataSet, tx)
|
|
164
|
+
|
|
165
|
+
// When
|
|
166
|
+
const dataOoc = await dataOocFactory.createWithDataSetAndSample(
|
|
167
|
+
{ state: DataOocStatus.ISSUED },
|
|
168
|
+
dataSet,
|
|
169
|
+
dataSample,
|
|
170
|
+
tx
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
// Then: 관계 확인
|
|
174
|
+
expect(dataOoc.dataSample?.id).toBe(dataSample.id)
|
|
175
|
+
expect(dataOoc.dataSet?.id).toBe(dataSet.id)
|
|
176
|
+
expect(dataOoc.domain?.id).toBe(domain.id)
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('DataOoc 생성 엣지 케이스', () => {
|
|
182
|
+
it('ooc=true, oos=true인 경우 둘 다 저장되어야 한다', async () => {
|
|
183
|
+
await withTestTransaction(async (context) => {
|
|
184
|
+
const { tx, domain, user } = context.state
|
|
185
|
+
|
|
186
|
+
// Given
|
|
187
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
188
|
+
const dataSample = await dataSampleFactory.createWithDataSet(
|
|
189
|
+
{
|
|
190
|
+
data: { temperature: 150 }, // 스펙 초과
|
|
191
|
+
ooc: true,
|
|
192
|
+
oos: true
|
|
193
|
+
},
|
|
194
|
+
dataSet,
|
|
195
|
+
domain,
|
|
196
|
+
tx
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
// When
|
|
200
|
+
const dataOoc = await tx.save('DataOoc', {
|
|
201
|
+
name: `OOC-${dataSet.name}`,
|
|
202
|
+
data: dataSample.data,
|
|
203
|
+
ooc: true,
|
|
204
|
+
oos: true,
|
|
205
|
+
collectedAt: new Date(),
|
|
206
|
+
history: [
|
|
207
|
+
{
|
|
208
|
+
user: { id: user.id, name: user.name },
|
|
209
|
+
state: DataOocStatus.ISSUED,
|
|
210
|
+
timestamp: new Date()
|
|
211
|
+
}
|
|
212
|
+
],
|
|
213
|
+
state: DataOocStatus.ISSUED,
|
|
214
|
+
dataSample,
|
|
215
|
+
dataSet,
|
|
216
|
+
domain
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
// Then
|
|
220
|
+
expect(dataOoc.ooc).toBe(true)
|
|
221
|
+
expect(dataOoc.oos).toBe(true)
|
|
222
|
+
})
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
it('collectedAt이 정확히 복사되어야 한다', async () => {
|
|
226
|
+
await withTestTransaction(async (context) => {
|
|
227
|
+
const { tx, domain, user } = context.state
|
|
228
|
+
|
|
229
|
+
// Given
|
|
230
|
+
const specificDate = new Date('2024-01-15T10:30:00.000Z')
|
|
231
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
232
|
+
const dataSample = await dataSampleFactory.createWithDataSet(
|
|
233
|
+
{
|
|
234
|
+
collectedAt: specificDate,
|
|
235
|
+
ooc: true
|
|
236
|
+
},
|
|
237
|
+
dataSet,
|
|
238
|
+
domain,
|
|
239
|
+
tx
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
// When
|
|
243
|
+
const dataOoc = await tx.save('DataOoc', {
|
|
244
|
+
name: `OOC-${dataSet.name}`,
|
|
245
|
+
data: dataSample.data,
|
|
246
|
+
ooc: true,
|
|
247
|
+
collectedAt: dataSample.collectedAt,
|
|
248
|
+
history: [
|
|
249
|
+
{
|
|
250
|
+
user: { id: user.id, name: user.name },
|
|
251
|
+
state: DataOocStatus.ISSUED,
|
|
252
|
+
timestamp: dataSample.collectedAt
|
|
253
|
+
}
|
|
254
|
+
],
|
|
255
|
+
state: DataOocStatus.ISSUED,
|
|
256
|
+
dataSample,
|
|
257
|
+
dataSet,
|
|
258
|
+
domain
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
// Then
|
|
262
|
+
expect(dataOoc.collectedAt).toEqual(specificDate)
|
|
263
|
+
})
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
it('workDate와 workShift가 정확히 복사되어야 한다', async () => {
|
|
267
|
+
await withTestTransaction(async (context) => {
|
|
268
|
+
const { tx, domain, user } = context.state
|
|
269
|
+
|
|
270
|
+
// Given
|
|
271
|
+
const dataSet = await dataSetFactory.createWithDomain({}, domain, tx)
|
|
272
|
+
const dataSample = await dataSampleFactory.createWithDataSet(
|
|
273
|
+
{
|
|
274
|
+
workDate: '2024-01-15',
|
|
275
|
+
workShift: 'night',
|
|
276
|
+
ooc: true
|
|
277
|
+
},
|
|
278
|
+
dataSet,
|
|
279
|
+
domain,
|
|
280
|
+
tx
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
// When
|
|
284
|
+
const dataOoc = await tx.save('DataOoc', {
|
|
285
|
+
name: `OOC-${dataSet.name}`,
|
|
286
|
+
data: dataSample.data,
|
|
287
|
+
ooc: true,
|
|
288
|
+
collectedAt: dataSample.collectedAt,
|
|
289
|
+
workDate: dataSample.workDate,
|
|
290
|
+
workShift: dataSample.workShift,
|
|
291
|
+
history: [
|
|
292
|
+
{
|
|
293
|
+
user: { id: user.id, name: user.name },
|
|
294
|
+
state: DataOocStatus.ISSUED,
|
|
295
|
+
timestamp: new Date()
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
state: DataOocStatus.ISSUED,
|
|
299
|
+
dataSample,
|
|
300
|
+
dataSet,
|
|
301
|
+
domain
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
// Then
|
|
305
|
+
expect(dataOoc.workDate).toBe('2024-01-15')
|
|
306
|
+
expect(dataOoc.workShift).toBe('night')
|
|
307
|
+
})
|
|
308
|
+
})
|
|
309
|
+
})
|
|
310
|
+
})
|