Skip to content

Commit 778cf8e

Browse files
committed
feat: add isAdmin field to User model
- Added isAdmin field to User model - Updated User model documentation - Updated tests for the new field
1 parent 8192edd commit 778cf8e

File tree

5 files changed

+87
-22
lines changed

5 files changed

+87
-22
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This package provides the following core data models:
2727
* **`Category`**: Represents a news category with an ID, name, and optional description and icon URL.
2828
* **`Source`**: Represents a news source, including ID, name, description, URL, language, optional headquarters (`Country`), and a `SourceType` enum (e.g., `newsAgency`, `blog`).
2929
* **`Country`**: Represents a country with an ID, ISO code, name, and flag URL.
30-
* **`User`**: Represents an authenticated user within the system.
30+
* **`User`**: Represents an authenticated user within the system, including an `isAdmin` flag.
3131
* **`PaginatedResponse<T>`**: A generic class for handling paginated API responses, containing a list of items (`items`), a `cursor` for the next page, and a `hasMore` flag.
3232
* **`AuthSuccessResponse`**: Represents the successful result of an authentication operation, typically containing the authenticated user details and an access token.
3333
* **`SuccessApiResponse<T>`**: A generic wrapper for successful API responses, containing the main `data` payload (of type `T`) and optional `ResponseMetadata`.

lib/src/models/user.dart

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@ part 'user.g.dart';
77
///
88
/// This model holds basic information about the user, including their
99
/// unique identifier, email (if available), and whether they are
10-
/// authenticated anonymously.
10+
/// authenticated anonymously. It also includes an [isAdmin] flag
11+
/// to indicate administrative privileges.
1112
@JsonSerializable()
1213
class User extends Equatable {
1314
/// Creates a new [User] instance.
1415
///
15-
/// Requires a unique [id] and an [isAnonymous] flag.
16+
/// Requires a unique [id], an [isAnonymous] flag, and an [isAdmin] flag.
1617
/// The [email] is optional and typically present only for non-anonymous
1718
/// users who have verified their email address.
18-
const User({required this.id, required this.isAnonymous, this.email});
19+
const User({
20+
required this.id,
21+
required this.isAnonymous,
22+
required this.isAdmin,
23+
this.email,
24+
});
1925

2026
/// Creates a User from JSON data.
2127
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
@@ -35,14 +41,17 @@ class User extends Equatable {
3541
/// `false` otherwise.
3642
final bool isAnonymous;
3743

44+
/// Indicates whether the user has administrative privileges.
45+
final bool isAdmin;
46+
3847
/// Converts this User instance to JSON data.
3948
Map<String, dynamic> toJson() => _$UserToJson(this);
4049

4150
@override
42-
List<Object?> get props => [id, email, isAnonymous];
51+
List<Object?> get props => [id, email, isAnonymous, isAdmin];
4352

4453
@override
4554
String toString() {
46-
return 'User(id: $id, email: $email, isAnonymous: $isAnonymous)';
55+
return 'User(id: $id, email: $email, isAnonymous: $isAnonymous, isAdmin: $isAdmin)';
4756
}
4857
}

lib/src/models/user.g.dart

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/src/models/auth_success_response_test.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ void main() {
88
id: 'user-123',
99
email: 'test@example.com',
1010
isAnonymous: false,
11+
isAdmin: false,
1112
);
1213
const testToken = 'sample-jwt-token';
1314

@@ -95,6 +96,7 @@ void main() {
9596
id: 'user-456',
9697
email: 'updated@example.com',
9798
isAnonymous: true,
99+
isAdmin: false,
98100
);
99101
final copiedResponse = authSuccessResponse.copyWith(user: updatedUser);
100102

@@ -115,7 +117,7 @@ void main() {
115117
});
116118

117119
test('should create a copy with both user and token updated', () {
118-
const updatedUser = User(id: 'user-789', isAnonymous: true);
120+
const updatedUser = User(id: 'user-789', isAnonymous: true, isAdmin: false);
119121
const updatedToken = 'another-token-xyz';
120122
final copiedResponse = authSuccessResponse.copyWith(
121123
user: updatedUser,
@@ -137,7 +139,7 @@ void main() {
137139
});
138140

139141
test('should not equate instances with different users', () {
140-
const differentUser = User(id: 'diff-user', isAnonymous: false);
142+
const differentUser = User(id: 'diff-user', isAnonymous: false, isAdmin: false);
141143
const response1 = AuthSuccessResponse(user: testUser, token: testToken);
142144
const response2 = AuthSuccessResponse(
143145
user: differentUser,

test/src/models/user_test.dart

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,103 @@ void main() {
88

99
test('supports value equality', () {
1010
expect(
11-
const User(id: id, email: email, isAnonymous: false),
12-
equals(const User(id: id, email: email, isAnonymous: false)),
11+
const User(id: id, email: email, isAnonymous: false, isAdmin: false),
12+
equals(
13+
const User(id: id, email: email, isAnonymous: false, isAdmin: false),
14+
),
1315
);
1416
expect(
15-
const User(id: id, email: email, isAnonymous: false),
17+
const User(id: id, email: email, isAnonymous: false, isAdmin: false),
1618
isNot(
17-
equals(const User(id: 'other-id', email: email, isAnonymous: false)),
19+
equals(
20+
const User(
21+
id: 'other-id',
22+
email: email,
23+
isAnonymous: false,
24+
isAdmin: false,
25+
),
26+
),
1827
),
1928
);
2029
expect(
21-
const User(id: id, email: email, isAnonymous: false),
30+
const User(id: id, email: email, isAnonymous: false, isAdmin: false),
2231
isNot(
2332
equals(
24-
const User(id: id, email: 'other@example.com', isAnonymous: false),
33+
const User(
34+
id: id,
35+
email: 'other@example.com',
36+
isAnonymous: false,
37+
isAdmin: false,
38+
),
2539
),
2640
),
2741
);
2842
expect(
29-
const User(id: id, email: email, isAnonymous: false),
30-
isNot(equals(const User(id: id, email: email, isAnonymous: true))),
43+
const User(id: id, email: email, isAnonymous: false, isAdmin: false),
44+
isNot(
45+
equals(
46+
const User(id: id, email: email, isAnonymous: true, isAdmin: false),
47+
),
48+
),
49+
);
50+
expect(
51+
const User(id: id, email: email, isAnonymous: false, isAdmin: false),
52+
isNot(
53+
equals(
54+
const User(id: id, email: email, isAnonymous: false, isAdmin: true),
55+
),
56+
),
3157
);
3258
});
3359

3460
test('has correct toString', () {
3561
expect(
36-
const User(id: id, email: email, isAnonymous: false).toString(),
37-
equals('User(id: $id, email: $email, isAnonymous: false)'),
62+
const User(
63+
id: id,
64+
email: email,
65+
isAnonymous: false,
66+
isAdmin: false,
67+
).toString(),
68+
equals(
69+
'User(id: $id, email: $email, isAnonymous: false, isAdmin: false)',
70+
),
3871
);
3972
expect(
40-
const User(id: id, isAnonymous: true).toString(),
41-
equals('User(id: $id, email: null, isAnonymous: true)'),
73+
const User(id: id, isAnonymous: true, isAdmin: false).toString(),
74+
equals('User(id: $id, email: null, isAnonymous: true, isAdmin: false)'),
75+
);
76+
expect(
77+
const User(id: id, isAnonymous: false, isAdmin: true).toString(),
78+
equals('User(id: $id, email: null, isAnonymous: false, isAdmin: true)'),
4279
);
4380
});
4481

4582
// Basic test for JSON serialization - assumes build_runner generated correctly
4683
test('can be serialized and deserialized', () {
47-
const user = User(id: id, email: email, isAnonymous: false);
84+
const user = User(
85+
id: id,
86+
email: email,
87+
isAnonymous: false,
88+
isAdmin: false,
89+
);
4890
final json = user.toJson();
4991
final deserializedUser = User.fromJson(json);
5092
expect(deserializedUser, equals(user));
5193

52-
const anonUser = User(id: id, isAnonymous: true);
94+
const anonUser = User(id: id, isAnonymous: true, isAdmin: false);
5395
final anonJson = anonUser.toJson();
5496
final deserializedAnonUser = User.fromJson(anonJson);
5597
expect(deserializedAnonUser, equals(anonUser));
98+
99+
const adminUser = User(
100+
id: id,
101+
email: email,
102+
isAnonymous: false,
103+
isAdmin: true,
104+
);
105+
final adminJson = adminUser.toJson();
106+
final deserializedAdminUser = User.fromJson(adminJson);
107+
expect(deserializedAdminUser, equals(adminUser));
56108
});
57109
});
58110
}

0 commit comments

Comments
 (0)