tangled
alpha
login
or
join now
tranquil.farm
/
tranquil-pds
147
fork
atom
Our Personal Data Server from scratch!
tranquil.farm
oauth
atproto
pds
rust
postgresql
objectstorage
fun
147
fork
atom
overview
issues
18
pulls
2
pipelines
fix: no preference dedup needed
oyster.cafe
1 month ago
ebccbce0
c19904f6
+64
2 changed files
expand all
collapse all
unified
split
crates
tranquil-pds
tests
actor.rs
migrations
20260121_preferences_allow_duplicate_types.sql
+63
crates/tranquil-pds/tests/actor.rs
···
75
75
}
76
76
77
77
#[tokio::test]
78
78
+
async fn test_put_preferences_multiple_same_type() {
79
79
+
let client = client();
80
80
+
let base = base_url().await;
81
81
+
let (token, _did) = create_account_and_login(&client).await;
82
82
+
let prefs = json!({
83
83
+
"preferences": [
84
84
+
{
85
85
+
"$type": "app.bsky.actor.defs#adultContentPref",
86
86
+
"enabled": false
87
87
+
},
88
88
+
{
89
89
+
"$type": "app.bsky.actor.defs#contentLabelPref",
90
90
+
"label": "dogs",
91
91
+
"visibility": "show"
92
92
+
},
93
93
+
{
94
94
+
"$type": "app.bsky.actor.defs#contentLabelPref",
95
95
+
"label": "cats",
96
96
+
"visibility": "warn"
97
97
+
}
98
98
+
]
99
99
+
});
100
100
+
let resp = client
101
101
+
.post(format!("{}/xrpc/app.bsky.actor.putPreferences", base))
102
102
+
.header("Authorization", format!("Bearer {}", token))
103
103
+
.json(&prefs)
104
104
+
.send()
105
105
+
.await
106
106
+
.unwrap();
107
107
+
assert_eq!(resp.status(), 200);
108
108
+
let resp = client
109
109
+
.get(format!("{}/xrpc/app.bsky.actor.getPreferences", base))
110
110
+
.header("Authorization", format!("Bearer {}", token))
111
111
+
.send()
112
112
+
.await
113
113
+
.unwrap();
114
114
+
assert_eq!(resp.status(), 200);
115
115
+
let body: Value = resp.json().await.unwrap();
116
116
+
let prefs_arr = body["preferences"].as_array().unwrap();
117
117
+
assert_eq!(prefs_arr.len(), 3);
118
118
+
let adult_pref = prefs_arr
119
119
+
.iter()
120
120
+
.find(|p| p.get("$type").and_then(|t| t.as_str()) == Some("app.bsky.actor.defs#adultContentPref"));
121
121
+
assert!(adult_pref.is_some());
122
122
+
assert_eq!(adult_pref.unwrap()["enabled"], false);
123
123
+
let content_label_prefs: Vec<&Value> = prefs_arr
124
124
+
.iter()
125
125
+
.filter(|p| p.get("$type").and_then(|t| t.as_str()) == Some("app.bsky.actor.defs#contentLabelPref"))
126
126
+
.collect();
127
127
+
assert_eq!(content_label_prefs.len(), 2);
128
128
+
let dogs_pref = content_label_prefs
129
129
+
.iter()
130
130
+
.find(|p| p.get("label").and_then(|l| l.as_str()) == Some("dogs"));
131
131
+
assert!(dogs_pref.is_some());
132
132
+
assert_eq!(dogs_pref.unwrap()["visibility"], "show");
133
133
+
let cats_pref = content_label_prefs
134
134
+
.iter()
135
135
+
.find(|p| p.get("label").and_then(|l| l.as_str()) == Some("cats"));
136
136
+
assert!(cats_pref.is_some());
137
137
+
assert_eq!(cats_pref.unwrap()["visibility"], "warn");
138
138
+
}
139
139
+
140
140
+
#[tokio::test]
78
141
async fn test_put_preferences_no_auth() {
79
142
let client = client();
80
143
let base = base_url().await;
+1
migrations/20260121_preferences_allow_duplicate_types.sql
···
1
1
+
ALTER TABLE account_preferences DROP CONSTRAINT IF EXISTS account_preferences_user_id_name_key;