Skip to content

Commit da1425a

Browse files
committed
Implemented cart service tests
1 parent 9e1d246 commit da1425a

File tree

2 files changed

+162
-1
lines changed

2 files changed

+162
-1
lines changed

ecommerce_app/lib/src/features/cart/domain/cart.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'dart:convert';
22

3+
import 'package:flutter/foundation.dart';
4+
35
import 'package:ecommerce_app/src/features/cart/domain/item.dart';
46
import 'package:ecommerce_app/src/features/products/domain/product.dart';
57

@@ -30,6 +32,16 @@ class Cart {
3032

3133
@override
3234
String toString() => 'Cart(items: $items)';
35+
36+
@override
37+
bool operator ==(Object other) {
38+
if (identical(this, other)) return true;
39+
40+
return other is Cart && mapEquals(other.items, items);
41+
}
42+
43+
@override
44+
int get hashCode => items.hashCode;
3345
}
3446

3547
extension CartItems on Cart {

ecommerce_app/test/src/features/cart/application/cart_service_test.dart

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
import 'package:ecommerce_app/src/features/authentication/data/fake_auth_repository.dart';
2+
import 'package:ecommerce_app/src/features/authentication/domain/app_user.dart';
23
import 'package:ecommerce_app/src/features/cart/application/cart_service.dart';
34
import 'package:ecommerce_app/src/features/cart/data/local/local_cart_repository.dart';
45
import 'package:ecommerce_app/src/features/cart/data/remote/remote_cart_repository.dart';
6+
import 'package:ecommerce_app/src/features/cart/domain/cart.dart';
7+
import 'package:ecommerce_app/src/features/cart/domain/item.dart';
58
import 'package:flutter_riverpod/flutter_riverpod.dart';
69
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:mocktail/mocktail.dart';
711

812
import '../../../mocks.dart';
913

1014
void main() {
15+
setUpAll(() {
16+
registerFallbackValue(const Cart());
17+
});
18+
const testUser = AppUser(uid: 'abc');
19+
1120
late MockAuthRepository authRepository;
1221
late MockRemoteCartRepository remoteCartRepository;
1322
late MockLocalCartRepository localCartRepository;
@@ -16,6 +25,7 @@ void main() {
1625
remoteCartRepository = MockRemoteCartRepository();
1726
localCartRepository = MockLocalCartRepository();
1827
});
28+
1929
CartService makeCartService() {
2030
final container = ProviderContainer(
2131
overrides: [
@@ -30,11 +40,150 @@ void main() {
3040

3141
group('setItem', () {
3242
test('null user, writes item to local cart', () async {
43+
// setup
44+
const expectedCart = Cart({'123': 1});
45+
when(() => authRepository.currentUser).thenReturn(null);
46+
when(localCartRepository.fetchCart).thenAnswer(
47+
(_) => Future.value(const Cart()),
48+
);
49+
when(() => localCartRepository.setCart(expectedCart)).thenAnswer(
50+
(_) => Future.value(),
51+
);
3352
final cartService = makeCartService();
53+
// run
54+
await cartService.setItem(
55+
const Item(productId: '123', quantity: 1),
56+
);
57+
// verify
58+
verify(
59+
() => localCartRepository.setCart(expectedCart),
60+
).called(1);
61+
verifyNever(
62+
() => remoteCartRepository.setCart(any(), any()),
63+
);
3464
});
3565

3666
test('non-null user, writes item to remote cart', () async {
37-
// TODO: Implement
67+
// setup
68+
const expectedCart = Cart({'123': 1});
69+
when(() => authRepository.currentUser).thenReturn(testUser);
70+
when(() => remoteCartRepository.fetchCart(testUser.uid)).thenAnswer(
71+
(_) => Future.value(const Cart()),
72+
);
73+
when(() => remoteCartRepository.setCart(testUser.uid, expectedCart))
74+
.thenAnswer(
75+
(_) => Future.value(),
76+
);
77+
final cartService = makeCartService();
78+
// run
79+
await cartService.setItem(
80+
const Item(productId: '123', quantity: 1),
81+
);
82+
// verify
83+
verify(
84+
() => remoteCartRepository.setCart(testUser.uid, expectedCart),
85+
).called(1);
86+
verifyNever(
87+
() => localCartRepository.setCart(any()),
88+
);
89+
});
90+
});
91+
92+
group('addItem', () {
93+
test('null user, adds item to local cart', () async {
94+
// setup
95+
const initialCart = Cart({'123': 2});
96+
const expectedCart = Cart({'123': 3});
97+
when(() => authRepository.currentUser).thenReturn(null); // null user
98+
when(localCartRepository.fetchCart).thenAnswer(
99+
(_) => Future.value(initialCart), // empty cart
100+
);
101+
when(() => localCartRepository.setCart(expectedCart)).thenAnswer(
102+
(_) => Future.value(),
103+
);
104+
final cartService = makeCartService();
105+
// run
106+
await cartService.addItem(const Item(productId: '123', quantity: 1));
107+
// verify
108+
verify(
109+
() => localCartRepository.setCart(expectedCart),
110+
).called(1);
111+
verifyNever(
112+
() => remoteCartRepository.setCart(any(), any()),
113+
);
114+
});
115+
116+
test('non-null user, adds item to remote cart', () async {
117+
// setup
118+
const initialCart = Cart({'123': 2});
119+
const expectedCart = Cart({'123': 3});
120+
when(() => authRepository.currentUser).thenReturn(testUser); // null user
121+
when(() => remoteCartRepository.fetchCart(testUser.uid)).thenAnswer(
122+
(_) => Future.value(initialCart), // empty cart
123+
);
124+
when(() => remoteCartRepository.setCart(testUser.uid, expectedCart))
125+
.thenAnswer(
126+
(_) => Future.value(),
127+
);
128+
final cartService = makeCartService();
129+
// run
130+
await cartService.addItem(const Item(productId: '123', quantity: 1));
131+
// verify
132+
verifyNever(
133+
() => localCartRepository.setCart(any()),
134+
);
135+
verify(
136+
() => remoteCartRepository.setCart(testUser.uid, expectedCart),
137+
).called(1);
138+
});
139+
});
140+
141+
group('removeItem', () {
142+
test('null user, removes item from local cart', () async {
143+
// setup
144+
const initialCart = Cart({'123': 3, '456': 1});
145+
const expectedCart = Cart({'456': 1});
146+
when(() => authRepository.currentUser).thenReturn(null); // null user
147+
when(localCartRepository.fetchCart).thenAnswer(
148+
(_) => Future.value(initialCart), // empty cart
149+
);
150+
when(() => localCartRepository.setCart(expectedCart)).thenAnswer(
151+
(_) => Future.value(),
152+
);
153+
final cartService = makeCartService();
154+
// run
155+
await cartService.removeItemById('123');
156+
// verify
157+
verify(
158+
() => localCartRepository.setCart(expectedCart),
159+
).called(1);
160+
verifyNever(
161+
() => remoteCartRepository.setCart(any(), any()),
162+
);
163+
});
164+
165+
test('non-null user, removes item from remote cart', () async {
166+
// setup
167+
const initialCart = Cart({'123': 3, '456': 1});
168+
const expectedCart = Cart({'456': 1});
169+
when(() => authRepository.currentUser).thenReturn(testUser); // null user
170+
when(() => remoteCartRepository.fetchCart(testUser.uid)).thenAnswer(
171+
(_) => Future.value(initialCart), // empty cart
172+
);
173+
when(() => remoteCartRepository.setCart(testUser.uid, expectedCart))
174+
.thenAnswer(
175+
(_) => Future.value(),
176+
);
177+
final cartService = makeCartService();
178+
// run
179+
await cartService.removeItemById('123');
180+
// verify
181+
verifyNever(
182+
() => localCartRepository.setCart(any()),
183+
);
184+
verify(
185+
() => remoteCartRepository.setCart(testUser.uid, expectedCart),
186+
).called(1);
38187
});
39188
});
40189
}

0 commit comments

Comments
 (0)