Skip to content

Commit 0bbfa38

Browse files
committed
Refactors list view for easier testing
1 parent 2570ae1 commit 0bbfa38

File tree

2 files changed

+39
-15
lines changed

2 files changed

+39
-15
lines changed

desktop/src/@batch-flask/core/data/list-view/list-view.spec.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { BasicEntityGetter, BasicListGetter, DataCache, FilterBuilder, ListView,
22
import { LoadingStatus } from "@batch-flask/ui/loading";
33
import { List, OrderedSet } from "immutable";
44
import { from, of } from "rxjs";
5-
import { flatMap } from "rxjs/operators";
5+
import { switchMap } from "rxjs/operators";
66
import { FakeModel } from "../test/fake-model";
77

88
const fake1 = { id: "1", parentId: "parent-1", state: "active", name: "Fake1" };
@@ -62,6 +62,9 @@ describe("ListView", () => {
6262
let status: LoadingStatus;
6363
let error: ServerError;
6464

65+
let setKeysSpy: jasmine.Spy;
66+
let appendKeysSpy: jasmine.Spy;
67+
6568
beforeEach(() => {
6669
cache = new DataCache<FakeModel>();
6770
dataSpy = jasmine.createSpy("supplyDataSpy").and.callFake((params, options, nextLink) => {
@@ -92,6 +95,9 @@ describe("ListView", () => {
9295
view.hasMore.subscribe(x => hasMore = x);
9396
view.status.subscribe(x => status = x);
9497
view.error.subscribe(x => error = x);
98+
99+
setKeysSpy = spyOn<any>(view, "_setItemKeys").and.callThrough();
100+
appendKeysSpy = spyOn<any>(view, "_appendItemKeys").and.callThrough();
95101
});
96102

97103
afterEach(() => {
@@ -114,9 +120,11 @@ describe("ListView", () => {
114120

115121
it("It retrieve the next batch of items", (done) => {
116122
view.fetchNext().pipe(
117-
flatMap(() => view.fetchNext()),
123+
switchMap(() => view.fetchNext()),
118124
).subscribe(() => {
119125
expect(dataSpy).toHaveBeenCalledTimes(2);
126+
expect(setKeysSpy).toHaveBeenCalledTimes(2);
127+
expect(appendKeysSpy).toHaveBeenCalledTimes(1);
120128
expect(items.toJS()).toEqual([fake1, fake2, fake3, fake4, fake5]);
121129
expect(hasMore).toBe(false);
122130
done();
@@ -127,6 +135,8 @@ describe("ListView", () => {
127135
view.fetchAll().subscribe(() => {
128136
expect(items.toJS()).toEqual([fake1, fake2, fake3, fake4, fake5]);
129137
expect(dataSpy).toHaveBeenCalledTimes(2);
138+
expect(setKeysSpy).toHaveBeenCalledTimes(1);
139+
expect(appendKeysSpy).toHaveBeenCalledTimes(0);
130140
expect(hasMore).toBe(false);
131141
done();
132142
});
@@ -136,11 +146,14 @@ describe("ListView", () => {
136146
view.fetchNext().subscribe(() => {
137147
expect(dataSpy).toHaveBeenCalledTimes(1);
138148
const obs = view.refresh(true);
139-
expect(items.size).toBe(0, "Should have cleared the items");
149+
expect(items.size)
150+
.withContext("Should have cleared the items")
151+
.toBe(0);
140152

141153
obs.subscribe(() => {
142154
expect(dataSpy).toHaveBeenCalledTimes(2);
143-
155+
expect(setKeysSpy).toHaveBeenCalledTimes(3);
156+
expect(appendKeysSpy).toHaveBeenCalledTimes(0);
144157
expect(items.toJS()).toEqual([fake1, fake2, fake3]);
145158
done();
146159
});
@@ -151,12 +164,15 @@ describe("ListView", () => {
151164
view.fetchNext().subscribe(() => {
152165
expect(dataSpy).toHaveBeenCalledTimes(1);
153166
const obs = view.refresh(false);
154-
expect(items.size).not.toBe(0, "Should NOT have cleared the items");
167+
expect(items.size)
168+
.withContext("should NOT have cleared the items").not.toBe(0);
155169

156170
items = List(); // Make sure it get the new value
157171
obs.subscribe(() => {
158172
view.items.subscribe(x => items = x);
159173
expect(dataSpy).toHaveBeenCalledTimes(2);
174+
expect(setKeysSpy).toHaveBeenCalledTimes(2);
175+
expect(appendKeysSpy).toHaveBeenCalledTimes(0);
160176
expect(items.toJS()).toEqual([fake1, fake2, fake3]);
161177
done();
162178
});

desktop/src/@batch-flask/core/data/list-view/list-view.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ export class ListView<TEntity extends Record<any>, TParams> extends GenericView<
3636
this._getter = config.getter;
3737
this._options = new ListOptions(config.initialOptions || {});
3838

39-
this.items = combineLatest(
39+
this.items = combineLatest([
4040
this._params.pipe(switchMap(params => this.getCache(params).items)),
4141
this._itemKeys.pipe(distinctUntilChanged()),
4242
this._prepend.pipe(distinctUntilChanged()),
4343
this._params,
44-
).pipe(
44+
]).pipe(
4545
map(([items, itemKeys, prependKeys, params]) => {
4646
prependKeys = prependKeys.filter((x: string) => !itemKeys.has(x)) as any;
4747

@@ -76,11 +76,11 @@ export class ListView<TEntity extends Record<any>, TParams> extends GenericView<
7676
this.hasMore = this._hasMore.asObservable();
7777

7878
this.deleted.subscribe((deletedKey) => {
79-
this._itemKeys.next(OrderedSet<string>(this._itemKeys.value.filter((key) => key !== deletedKey)));
79+
this._setItemKeys(OrderedSet<string>(this._itemKeys.value.filter((key) => key !== deletedKey)));
8080
});
8181

8282
this._cacheCleared.subscribe(() => {
83-
this._itemKeys.next(OrderedSet<string>([]));
83+
this._setItemKeys(OrderedSet<string>([]));
8484
this._handleChanges();
8585
this._hasMore.next(true);
8686
this.fetchNext();
@@ -103,7 +103,7 @@ export class ListView<TEntity extends Record<any>, TParams> extends GenericView<
103103
super.setOptions(new ListOptions(options));
104104
this._handleChanges();
105105
if (clearItems) {
106-
this._itemKeys.next(OrderedSet([]));
106+
this._setItemKeys(OrderedSet([]));
107107
}
108108
this._hasMore.next(true);
109109
}
@@ -221,18 +221,18 @@ export class ListView<TEntity extends Record<any>, TParams> extends GenericView<
221221
return;
222222
}
223223

224-
this._itemKeys.next(OrderedSet(OrderedSet([key]).concat(this._itemKeys.value)));
224+
this._setItemKeys(OrderedSet(OrderedSet([key]).concat(this._itemKeys.value)));
225225
this.cache.queryCache.addKeyToQuery(null, key);
226226
}
227227

228228
private _updateNewKeys(newKeys: OrderedSet<string>) {
229229
const currentKeys = this._itemKeys.value;
230230

231231
const last = this._lastRequest;
232-
if (last && (last.params !== this.params || last.options !== this._options)) {
233-
this._itemKeys.next(newKeys);
232+
if (last?.params !== this.params || last?.options !== this._options) {
233+
this._setItemKeys(newKeys);
234234
} else {
235-
this._itemKeys.next(OrderedSet<string>(currentKeys.concat(newKeys)));
235+
this._appendItemKeys(newKeys);
236236
}
237237

238238
this._lastRequest = { params: this.params, options: this._options };
@@ -248,7 +248,7 @@ export class ListView<TEntity extends Record<any>, TParams> extends GenericView<
248248
}
249249
const response = this._getter.fetchFromCache(this.params, this._options);
250250
if (!response) { return false; }
251-
this._itemKeys.next(this._retrieveKeys(response.items));
251+
this._setItemKeys(this._retrieveKeys(response.items));
252252
// this._lastRequest = { params: this._params, options: this._options };
253253
// this._hasMore.next(Boolean(response.nextLink));
254254
this._status.next(LoadingStatus.Ready);
@@ -262,4 +262,12 @@ export class ListView<TEntity extends Record<any>, TParams> extends GenericView<
262262
private _handleChanges() {
263263
this._nextLink = null;
264264
}
265+
266+
private _setItemKeys(keys: OrderedSet<string>) {
267+
this._itemKeys.next(keys);
268+
}
269+
270+
private _appendItemKeys(keys: OrderedSet<string>) {
271+
this._setItemKeys(OrderedSet(this._itemKeys.value.concat(keys)));
272+
}
265273
}

0 commit comments

Comments
 (0)