1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
// Tests for AssetManager Pallet
18
use crate::*;
19
use mock::*;
20

            
21
use frame_support::{assert_noop, assert_ok};
22

            
23
#[test]
24
1
fn registering_foreign_works() {
25
1
	ExtBuilder::default().build().execute_with(|| {
26
1
		assert_ok!(AssetManager::register_foreign_asset(
27
1
			RuntimeOrigin::root(),
28
1
			MockAssetType::MockAsset(1),
29
1
			0u32.into(),
30
1
			1u32.into(),
31
1
			true
32
1
		));
33

            
34
1
		assert_eq!(
35
1
			AssetManager::asset_id_type(1).unwrap(),
36
1
			MockAssetType::MockAsset(1)
37
1
		);
38
1
		assert_eq!(
39
1
			AssetManager::asset_type_id(MockAssetType::MockAsset(1)).unwrap(),
40
1
			1
41
1
		);
42
1
		expect_events(vec![crate::Event::ForeignAssetRegistered {
43
1
			asset_id: 1,
44
1
			asset: MockAssetType::MockAsset(1),
45
1
			metadata: 0u32,
46
1
		}])
47
1
	});
48
1
}
49

            
50
#[test]
51
1
fn test_asset_exists_error() {
52
1
	ExtBuilder::default().build().execute_with(|| {
53
1
		assert_ok!(AssetManager::register_foreign_asset(
54
1
			RuntimeOrigin::root(),
55
1
			MockAssetType::MockAsset(1),
56
1
			0u32.into(),
57
1
			1u32.into(),
58
1
			true
59
1
		));
60

            
61
1
		assert_eq!(
62
1
			AssetManager::asset_id_type(1).unwrap(),
63
1
			MockAssetType::MockAsset(1)
64
1
		);
65
1
		assert_noop!(
66
1
			AssetManager::register_foreign_asset(
67
1
				RuntimeOrigin::root(),
68
1
				MockAssetType::MockAsset(1),
69
1
				0u32.into(),
70
1
				1u32.into(),
71
1
				true
72
1
			),
73
1
			Error::<Test>::AssetAlreadyExists
74
1
		);
75
1
	});
76
1
}
77

            
78
#[test]
79
1
fn test_regular_user_cannot_call_extrinsics() {
80
1
	ExtBuilder::default().build().execute_with(|| {
81
1
		assert_noop!(
82
1
			AssetManager::register_foreign_asset(
83
1
				RuntimeOrigin::signed(1),
84
1
				MockAssetType::MockAsset(1),
85
1
				0u32.into(),
86
1
				1u32.into(),
87
1
				true
88
1
			),
89
1
			sp_runtime::DispatchError::BadOrigin
90
1
		);
91

            
92
1
		assert_noop!(
93
1
			AssetManager::change_existing_asset_type(
94
1
				RuntimeOrigin::signed(1),
95
1
				1,
96
1
				MockAssetType::MockAsset(2),
97
1
				1
98
1
			),
99
1
			sp_runtime::DispatchError::BadOrigin
100
1
		);
101
1
	});
102
1
}
103

            
104
#[test]
105
1
fn test_root_can_change_asset_id_type() {
106
1
	ExtBuilder::default().build().execute_with(|| {
107
1
		assert_ok!(AssetManager::register_foreign_asset(
108
1
			RuntimeOrigin::root(),
109
1
			MockAssetType::MockAsset(1),
110
1
			0u32.into(),
111
1
			1u32.into(),
112
1
			true
113
1
		));
114

            
115
1
		assert_ok!(AssetManager::change_existing_asset_type(
116
1
			RuntimeOrigin::root(),
117
1
			1,
118
1
			MockAssetType::MockAsset(2),
119
1
			1
120
1
		));
121

            
122
		// New associations are established
123
1
		assert_eq!(
124
1
			AssetManager::asset_id_type(1).unwrap(),
125
1
			MockAssetType::MockAsset(2)
126
1
		);
127
1
		assert_eq!(
128
1
			AssetManager::asset_type_id(MockAssetType::MockAsset(2)).unwrap(),
129
1
			1
130
1
		);
131

            
132
		// Old ones are deleted
133
1
		assert!(AssetManager::asset_type_id(MockAssetType::MockAsset(1)).is_none());
134

            
135
1
		expect_events(vec![
136
1
			crate::Event::ForeignAssetRegistered {
137
1
				asset_id: 1,
138
1
				asset: MockAssetType::MockAsset(1),
139
1
				metadata: 0,
140
1
			},
141
1
			crate::Event::ForeignAssetXcmLocationChanged {
142
1
				asset_id: 1,
143
1
				new_asset_type: MockAssetType::MockAsset(2),
144
1
			},
145
1
		])
146
1
	});
147
1
}
148

            
149
#[test]
150
1
fn test_asset_id_non_existent_error() {
151
1
	ExtBuilder::default().build().execute_with(|| {
152
1
		assert_noop!(
153
1
			AssetManager::change_existing_asset_type(
154
1
				RuntimeOrigin::root(),
155
1
				1,
156
1
				MockAssetType::MockAsset(2),
157
1
				1
158
1
			),
159
1
			Error::<Test>::AssetDoesNotExist
160
1
		);
161
1
	});
162
1
}
163

            
164
#[test]
165
1
fn test_root_can_remove_asset_association() {
166
1
	ExtBuilder::default().build().execute_with(|| {
167
1
		assert_ok!(AssetManager::register_foreign_asset(
168
1
			RuntimeOrigin::root(),
169
1
			MockAssetType::MockAsset(1),
170
1
			0u32.into(),
171
1
			1u32.into(),
172
1
			true
173
1
		));
174

            
175
1
		assert_ok!(AssetManager::remove_existing_asset_type(
176
1
			RuntimeOrigin::root(),
177
1
			1,
178
1
			1
179
1
		));
180

            
181
		// Mappings are deleted
182
1
		assert!(AssetManager::asset_type_id(MockAssetType::MockAsset(1)).is_none());
183
1
		assert!(AssetManager::asset_id_type(1).is_none());
184

            
185
1
		expect_events(vec![
186
1
			crate::Event::ForeignAssetRegistered {
187
1
				asset_id: 1,
188
1
				asset: MockAssetType::MockAsset(1),
189
1
				metadata: 0,
190
1
			},
191
1
			crate::Event::ForeignAssetRemoved {
192
1
				asset_id: 1,
193
1
				asset_type: MockAssetType::MockAsset(1),
194
1
			},
195
1
		])
196
1
	});
197
1
}
198

            
199
#[test]
200
1
fn test_removing_without_asset_units_per_second_does_not_panic() {
201
1
	ExtBuilder::default().build().execute_with(|| {
202
1
		assert_ok!(AssetManager::register_foreign_asset(
203
1
			RuntimeOrigin::root(),
204
1
			MockAssetType::MockAsset(1),
205
1
			0u32.into(),
206
1
			1u32.into(),
207
1
			true
208
1
		));
209

            
210
1
		assert_ok!(AssetManager::remove_existing_asset_type(
211
1
			RuntimeOrigin::root(),
212
1
			1,
213
1
			0
214
1
		));
215

            
216
		// Mappings are deleted
217
1
		assert!(AssetManager::asset_type_id(MockAssetType::MockAsset(1)).is_none());
218
1
		assert!(AssetManager::asset_id_type(1).is_none());
219

            
220
1
		expect_events(vec![
221
1
			crate::Event::ForeignAssetRegistered {
222
1
				asset_id: 1,
223
1
				asset: MockAssetType::MockAsset(1),
224
1
				metadata: 0,
225
1
			},
226
1
			crate::Event::ForeignAssetRemoved {
227
1
				asset_id: 1,
228
1
				asset_type: MockAssetType::MockAsset(1),
229
1
			},
230
1
		])
231
1
	});
232
1
}
233

            
234
#[test]
235
1
fn test_destroy_foreign_asset_also_removes_everything() {
236
1
	ExtBuilder::default().build().execute_with(|| {
237
1
		assert_ok!(AssetManager::register_foreign_asset(
238
1
			RuntimeOrigin::root(),
239
1
			MockAssetType::MockAsset(1),
240
1
			0u32.into(),
241
1
			1u32.into(),
242
1
			true
243
1
		));
244

            
245
1
		assert_ok!(AssetManager::destroy_foreign_asset(
246
1
			RuntimeOrigin::root(),
247
1
			1,
248
1
			0,
249
1
		));
250

            
251
		// Mappings are deleted
252
1
		assert!(AssetManager::asset_type_id(MockAssetType::MockAsset(1)).is_none());
253
1
		assert!(AssetManager::asset_id_type(1).is_none());
254

            
255
1
		expect_events(vec![
256
1
			crate::Event::ForeignAssetRegistered {
257
1
				asset_id: 1,
258
1
				asset: MockAssetType::MockAsset(1),
259
1
				metadata: 0,
260
1
			},
261
1
			crate::Event::ForeignAssetDestroyed {
262
1
				asset_id: 1,
263
1
				asset_type: MockAssetType::MockAsset(1),
264
1
			},
265
1
		])
266
1
	});
267
1
}