1
1
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
2
2
use hyper:: { Body , Request } ;
3
3
use routerify:: prelude:: * ;
4
- use serde:: Serialize ;
4
+ use serde:: { Serialize , Deserialize } ; // 添加 Deserialize
5
+ use tracing:: instrument;
5
6
6
7
use crate :: {
7
8
db:: { Change , Database } ,
8
9
util:: { pagination, ApiResult } ,
9
10
} ;
10
11
11
-
12
- #[ derive( Serialize ) ]
12
+ #[ derive( Serialize , Deserialize ) ] // 添加 Deserialize
13
13
pub struct ApiChange {
14
14
pub seq : i64 ,
15
15
pub r#type : String ,
@@ -28,9 +28,130 @@ impl From<Change> for ApiChange {
28
28
}
29
29
}
30
30
31
+ #[ instrument( name = "GET /api/_changes" , skip( req) , err) ]
31
32
pub async fn list_changes ( req : Request < Body > ) -> ApiResult < Vec < ApiChange > > {
32
33
let db = req. data :: < Database > ( ) . unwrap ( ) ;
33
34
let ( start, limit) = pagination ( & req) ;
34
35
let changes = db. list_changes ( start, limit) . await ?;
35
36
Ok ( changes. into_iter ( ) . map ( ApiChange :: from) . collect ( ) )
36
37
}
38
+
39
+
40
+ #[ cfg( test) ]
41
+ mod tests {
42
+ use super :: ApiChange ;
43
+ use crate :: ids:: PackageName ;
44
+ use crate :: ids:: ScopeName ;
45
+ use crate :: util:: test:: ApiResultExt ;
46
+ use crate :: util:: test:: TestSetup ;
47
+ use crate :: db:: ChangeType ;
48
+ use serde_json:: json;
49
+
50
+ #[ tokio:: test]
51
+ async fn list_empty_changes ( ) {
52
+ let mut t = TestSetup :: new ( ) . await ;
53
+
54
+ let changes = t
55
+ . http ( )
56
+ . get ( "/api/_changes" )
57
+ . call ( )
58
+ . await
59
+ . unwrap ( )
60
+ . expect_ok :: < Vec < ApiChange > > ( )
61
+ . await ;
62
+
63
+ assert ! ( changes. is_empty( ) ) ;
64
+ }
65
+
66
+ #[ tokio:: test]
67
+ async fn list_single_change ( ) {
68
+ let mut t = TestSetup :: new ( ) . await ;
69
+
70
+ t. ephemeral_database . create_change (
71
+ ChangeType :: PackageVersionAdded ,
72
+ & ScopeName :: new ( "test-scope" . to_string ( ) ) . unwrap ( ) ,
73
+ & PackageName :: new ( "test-package" . to_string ( ) ) . unwrap ( ) ,
74
+ json ! ( {
75
+ "version" : "1.0.0"
76
+ } ) ,
77
+ ) . await . unwrap ( ) ;
78
+
79
+ let changes = t
80
+ . http ( )
81
+ . get ( "/api/_changes" )
82
+ . call ( )
83
+ . await
84
+ . unwrap ( )
85
+ . expect_ok :: < Vec < ApiChange > > ( )
86
+ . await ;
87
+
88
+ assert_eq ! ( changes. len( ) , 1 ) ;
89
+ let change = & changes[ 0 ] ;
90
+ assert_eq ! ( change. r#type, ChangeType :: PackageVersionAdded . to_string( ) ) ;
91
+ assert_eq ! ( change. id, "@jsr/test-scope__test-package" ) ;
92
+ assert_eq ! ( change. changes[ "version" ] , "1.0.0" ) ;
93
+ }
94
+
95
+ #[ tokio:: test]
96
+ async fn list_changes_pagination ( ) {
97
+ let mut t = TestSetup :: new ( ) . await ;
98
+
99
+ // Create two changes
100
+ t. ephemeral_database . create_change (
101
+ ChangeType :: PackageVersionAdded ,
102
+ & ScopeName :: new ( "test-scope" . to_string ( ) ) . unwrap ( ) ,
103
+ & PackageName :: new ( "test-package-1" . to_string ( ) ) . unwrap ( ) ,
104
+ json ! ( {
105
+ "name" : "test-package-1" ,
106
+ } ) ,
107
+ ) . await . unwrap ( ) ;
108
+
109
+ t. ephemeral_database . create_change (
110
+ ChangeType :: PackageVersionAdded ,
111
+ & ScopeName :: new ( "test-scope" . to_string ( ) ) . unwrap ( ) ,
112
+ & PackageName :: new ( "test-package-2" . to_string ( ) ) . unwrap ( ) ,
113
+ json ! ( {
114
+ "version" : "1.0.0" ,
115
+ } ) ,
116
+ ) . await . unwrap ( ) ;
117
+
118
+ // Test limit parameter
119
+ let changes = t
120
+ . http ( )
121
+ . get ( "/api/_changes?limit=1&since=0" )
122
+ . call ( )
123
+ . await
124
+ . unwrap ( )
125
+ . expect_ok :: < Vec < ApiChange > > ( )
126
+ . await ;
127
+
128
+ assert_eq ! ( changes. len( ) , 1 ) ;
129
+ assert_eq ! ( changes[ 0 ] . id, "@jsr/test-scope__test-package-1" ) ;
130
+
131
+ // Test since parameter
132
+ let changes = t
133
+ . http ( )
134
+ . get ( & format ! ( "/api/_changes?since={}" , changes[ 0 ] . seq) )
135
+ . call ( )
136
+ . await
137
+ . unwrap ( )
138
+ . expect_ok :: < Vec < ApiChange > > ( )
139
+ . await ;
140
+
141
+ assert_eq ! ( changes. len( ) , 1 ) ;
142
+ assert_eq ! ( changes[ 0 ] . id, "@jsr/test-scope__test-package-2" ) ;
143
+
144
+ // Test since + limit combination
145
+ let changes = t
146
+ . http ( )
147
+ . get ( "/api/_changes?since=0&limit=1" )
148
+ . call ( )
149
+ . await
150
+ . unwrap ( )
151
+ . expect_ok :: < Vec < ApiChange > > ( )
152
+ . await ;
153
+
154
+ assert_eq ! ( changes. len( ) , 1 ) ;
155
+ assert_eq ! ( changes[ 0 ] . id, "@jsr/test-scope__test-package-1" ) ;
156
+ }
157
+ }
0 commit comments