-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path06_test_integrity_rules.sql
More file actions
237 lines (204 loc) · 5.77 KB
/
Copy path06_test_integrity_rules.sql
File metadata and controls
237 lines (204 loc) · 5.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
USE dpa_training;
GO
SET NOCOUNT ON;
SET XACT_ABORT ON;
GO
-- Test 1: max_score must be positive.
DECLARE @error_number INT = NULL;
DECLARE @assessment_id INT = (
SELECT TOP (1) assessment_id
FROM dpa.assessments
ORDER BY assessment_id
);
BEGIN TRANSACTION;
BEGIN TRY
UPDATE dpa.assessments
SET max_score = 0
WHERE assessment_id = @assessment_id;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) <> 547
THROW 51101, 'Integrity test failed: max_score = 0 was not rejected by a check constraint.', 1;
GO
-- Test 2: pass_score cannot exceed max_score.
DECLARE @error_number INT = NULL;
DECLARE @assessment_id INT = (
SELECT TOP (1) assessment_id
FROM dpa.assessments
ORDER BY assessment_id
);
BEGIN TRANSACTION;
BEGIN TRY
UPDATE dpa.assessments
SET pass_score = max_score + 1
WHERE assessment_id = @assessment_id;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) <> 547
THROW 51102, 'Integrity test failed: pass_score above max_score was not rejected.', 1;
GO
-- Test 3: result scores cannot be negative.
DECLARE @error_number INT = NULL;
DECLARE @result_id INT = (
SELECT TOP (1) result_id
FROM dpa.assessment_results
ORDER BY result_id
);
BEGIN TRANSACTION;
BEGIN TRY
UPDATE dpa.assessment_results
SET score = -1
WHERE result_id = @result_id;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) <> 547
THROW 51103, 'Integrity test failed: negative result score was not rejected.', 1;
GO
-- Test 4: result scores cannot exceed the assessment maximum.
DECLARE @error_number INT = NULL;
DECLARE @result_id INT = (
SELECT TOP (1) result_id
FROM dpa.assessment_results
ORDER BY result_id
);
BEGIN TRANSACTION;
BEGIN TRY
UPDATE ar
SET score = a.max_score + 1
FROM dpa.assessment_results ar
JOIN dpa.assessments a
ON a.assessment_id = ar.assessment_id
WHERE ar.result_id = @result_id;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) <> 51020
THROW 51104, 'Integrity test failed: score above max_score was not rejected by the result trigger.', 1;
GO
-- Test 5: an assessment maximum cannot be lowered below an existing score.
DECLARE @error_number INT = NULL;
DECLARE @assessment_id INT = (
SELECT TOP (1) a.assessment_id
FROM dpa.assessments a
JOIN dpa.assessment_results ar
ON ar.assessment_id = a.assessment_id
GROUP BY a.assessment_id, a.pass_score
HAVING MAX(ar.score) - 1 >= a.pass_score
ORDER BY a.assessment_id
);
DECLARE @new_max_score DECIMAL(5,2) = (
SELECT MAX(score) - 1
FROM dpa.assessment_results
WHERE assessment_id = @assessment_id
);
BEGIN TRANSACTION;
BEGIN TRY
UPDATE dpa.assessments
SET max_score = @new_max_score
WHERE assessment_id = @assessment_id;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) <> 51021
THROW 51105, 'Integrity test failed: max_score below an existing result was not rejected.', 1;
GO
-- Test 6: one learner can have only one result per assessment.
DECLARE @error_number INT = NULL;
DECLARE @assessment_id INT = (
SELECT TOP (1) assessment_id
FROM dpa.assessment_results
GROUP BY assessment_id
HAVING COUNT(*) >= 2
ORDER BY assessment_id
);
DECLARE @existing_learner_id INT = (
SELECT MIN(learner_id)
FROM dpa.assessment_results
WHERE assessment_id = @assessment_id
);
DECLARE @result_to_change INT = (
SELECT TOP (1) result_id
FROM dpa.assessment_results
WHERE assessment_id = @assessment_id
AND learner_id <> @existing_learner_id
ORDER BY result_id
);
BEGIN TRANSACTION;
BEGIN TRY
UPDATE dpa.assessment_results
SET learner_id = @existing_learner_id
WHERE result_id = @result_to_change;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) NOT IN (2601, 2627)
THROW 51106, 'Integrity test failed: duplicate learner-assessment result was not rejected.', 1;
GO
-- Test 7: assessment names must be unique inside a module.
DECLARE @error_number INT = NULL;
DECLARE @source_assessment_id INT;
DECLARE @source_module_id INT;
DECLARE @source_assessment_name NVARCHAR(100);
DECLARE @target_assessment_id INT;
SELECT TOP (1)
@source_assessment_id = assessment_id,
@source_module_id = module_id,
@source_assessment_name = assessment_name
FROM dpa.assessments
ORDER BY assessment_id;
SELECT TOP (1)
@target_assessment_id = assessment_id
FROM dpa.assessments
WHERE assessment_id <> @source_assessment_id
ORDER BY assessment_id;
BEGIN TRANSACTION;
BEGIN TRY
UPDATE dpa.assessments
SET module_id = @source_module_id,
assessment_name = @source_assessment_name
WHERE assessment_id = @target_assessment_id;
END TRY
BEGIN CATCH
SET @error_number = ERROR_NUMBER();
END CATCH;
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
IF ISNULL(@error_number, 0) NOT IN (2601, 2627)
THROW 51107, 'Integrity test failed: duplicate assessment name within a module was not rejected.', 1;
GO
IF EXISTS (
SELECT 1
FROM dpa.v_assessment_results
WHERE passed <> CAST(
CASE WHEN score >= pass_score THEN 1 ELSE 0 END
AS bit
)
)
THROW 51108, 'Integrity test failed: derived pass status is inconsistent.', 1;
GO
SELECT
CAST(7 AS INT) AS negative_tests_passed,
CAST(1 AS bit) AS derived_outcome_test_passed,
CAST(1 AS bit) AS integrity_test_suite_passed;
GO