Update test cases

This commit is contained in:
Ming Ming 2021-11-24 16:36:16 +08:00
parent 7b7dc1be8a
commit 2355f8e8a8
5 changed files with 663 additions and 19 deletions

View file

@ -11,12 +11,38 @@ void main() {
test("intial state", _initialState);
group("ListAlbumShareOutlierBlocQuery", () {
group("unshared album", () {
_testQueryUnsharedAlbumExtraFileShare();
_testQueryUnsharedAlbumExtraJsonShare();
_testQueryUnsharedAlbumExtraShare("extra share");
_testQueryUnsharedAlbumExtraJsonShare("extra json share");
});
group("shared album", () {
_testQuerySharedAlbumMissingFileShare();
_testQuerySharedAlbumMissingJsonShare();
group("owned", () {
_testQuerySharedAlbumMissingShare("missing share");
_testQuerySharedAlbumMissingManagedOtherShare(
"missing managed other share");
_testQuerySharedAlbumMissingUnmanagedOtherShare(
"missing unmanaged other share");
_testQuerySharedAlbumMissingJsonShare("missing json share");
_testQuerySharedAlbumExtraShare("extra share");
_testQuerySharedAlbumExtraManagedOtherShare(
"extra managed other share");
_testQuerySharedAlbumExtraUnmanagedOtherShare(
"extra unmanaged other share");
_testQuerySharedAlbumExtraJsonShare("extra json share");
});
group("not owned", () {
_testQuerySharedAlbumNotOwnedMissingShareToOwner("missing share");
_testQuerySharedAlbumNotOwnedMissingManagedShare(
"missing managed share");
_testQuerySharedAlbumNotOwnedMissingUnmanagedShare(
"missing unmanaged share");
_testQuerySharedAlbumNotOwnedMissingJsonShare("missing json share");
_testQuerySharedAlbumNotOwnedExtraManagedShare("extra managed share");
_testQuerySharedAlbumNotOwnedExtraUnmanagedShare(
"extra unmanaged share");
_testQuerySharedAlbumNotOwnedExtraJsonShare("extra json share");
});
});
});
});
@ -33,7 +59,7 @@ void _initialState() {
/// Query an album that is not shared, but with shared file (admin -> user1)
///
/// Expect: emit the file with extra share (admin -> user1)
void _testQueryUnsharedAlbumExtraFileShare() {
void _testQueryUnsharedAlbumExtraShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
@ -46,7 +72,7 @@ void _testQueryUnsharedAlbumExtraFileShare() {
util.buildSharee(shareWith: "user1".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
"extra file share",
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
@ -66,7 +92,7 @@ void _testQueryUnsharedAlbumExtraFileShare() {
/// (admin -> user1)
///
/// Expect: emit the json file with extra share (admin -> user1)
void _testQueryUnsharedAlbumExtraJsonShare() {
void _testQueryUnsharedAlbumExtraJsonShare(String description) {
final account = util.buildAccount();
final album = util.AlbumBuilder().build();
final albumFile = album.albumFile!;
@ -77,7 +103,7 @@ void _testQueryUnsharedAlbumExtraJsonShare() {
util.buildSharee(shareWith: "user1".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
"extra json share",
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
@ -93,10 +119,10 @@ void _testQueryUnsharedAlbumExtraJsonShare() {
);
}
/// Query a shared album (admin -> user1), with file not shared
/// Query a shared album (admin -> user1), with file not shared (admin -> user1)
///
/// Expect: emit the file with missing share (admin -> user1)
void _testQuerySharedAlbumMissingFileShare() {
void _testQuerySharedAlbumMissingShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
@ -113,7 +139,7 @@ void _testQuerySharedAlbumMissingFileShare() {
util.buildSharee(shareWith: "user1".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
"missing file share",
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
@ -128,10 +154,91 @@ void _testQuerySharedAlbumMissingFileShare() {
);
}
/// Query a shared album (admin -> user1, user2), with file added by user1,
/// managed by admin, not shared (admin -> user2)
///
/// Expect: emit empty list
void _testQuerySharedAlbumMissingManagedOtherShare(String description) {
final account = util.buildAccount();
final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("user1/test1.jpg", ownerId: "user1"))
.build();
final album = (util.AlbumBuilder()
// added before album shared, thus managed by album owner
..addFileItem(files[0], addedBy: "user1")
..addShare("user1", sharedAt: DateTime.utc(2021, 1, 2, 3, 4, 5))
..addShare("user2", sharedAt: DateTime.utc(2021, 1, 2, 3, 4, 5)))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(id: "1", file: albumFile, shareWith: "user2"),
util.buildShare(
id: "2", file: files[0], uidOwner: "user1", shareWith: "admin"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(files[0], [
ListAlbumShareOutlierMissingShareItem("user2".toCi(), "user2"),
]),
]),
],
);
}
/// Query a shared album (admin -> user1, user2), with file added by user1,
/// managed by user1, not shared (user1 -> user2)
///
/// Expect: emit empty list
void _testQuerySharedAlbumMissingUnmanagedOtherShare(String description) {
final account = util.buildAccount();
final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("user1/test1.jpg", ownerId: "user1"))
.build();
final album = (util.AlbumBuilder()
// added after album shared, thus managed by adder
..addFileItem(files[0],
addedBy: "user1", addedAt: DateTime.utc(2021, 1, 2, 3, 4, 5))
..addShare("user1")
..addShare("user2"))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(id: "1", file: albumFile, shareWith: "user2"),
util.buildShare(
id: "2", file: files[0], uidOwner: "user1", shareWith: "admin"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, []),
],
);
}
/// Query a shared album (admin -> user1), with album json not shared
///
/// Expect: emit the file with missing share (admin -> user1)
void _testQuerySharedAlbumMissingJsonShare() {
void _testQuerySharedAlbumMissingJsonShare(String description) {
final account = util.buildAccount();
final album = (util.AlbumBuilder()..addShare("user1")).build();
final albumFile = album.albumFile!;
@ -140,7 +247,7 @@ void _testQuerySharedAlbumMissingJsonShare() {
util.buildSharee(shareWith: "user1".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
"missing json share",
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
@ -154,3 +261,415 @@ void _testQuerySharedAlbumMissingJsonShare() {
],
);
}
/// Query a shared album (admin -> user1), with file shared
/// (admin -> user1, user2)
///
/// Expect: emit the file with extra share (admin -> user2)
void _testQuerySharedAlbumExtraShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder()
..addFileItem(files[0])
..addShare("user1"))
.build();
final file1 = files[0];
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(id: "1", file: files[0], shareWith: "user1"),
util.buildShare(id: "2", file: files[0], shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(file1, [
ListAlbumShareOutlierExtraShareItem(
util.buildShare(id: "2", file: files[0], shareWith: "user2")),
]),
]),
],
);
}
/// Query a shared album (admin -> user1), with file added by user1,
/// managed by admin, shared (admin -> user1, user2)
///
/// Expect: emit the file with extra share (admin -> user2)
void _testQuerySharedAlbumExtraManagedOtherShare(String description) {
final account = util.buildAccount();
final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("user1/test1.jpg", ownerId: "user1"))
.build();
final album = (util.AlbumBuilder()
// added before album shared, thus managed by album owner
..addFileItem(files[0], addedBy: "user1")
..addShare("user1", sharedAt: DateTime.utc(2021, 1, 2, 3, 4, 5)))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(
id: "1", file: files[0], uidOwner: "user1", shareWith: "admin"),
util.buildShare(id: "2", file: files[0], shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(files[0], [
ListAlbumShareOutlierExtraShareItem(
util.buildShare(id: "2", file: files[0], shareWith: "user2")),
]),
]),
],
);
}
/// Query a shared album (admin -> user1), with file added by user1, managed by
/// user1, shared (user1 -> admin, user2)
///
/// Expect: emit empty list
void _testQuerySharedAlbumExtraUnmanagedOtherShare(String description) {
final account = util.buildAccount();
final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("user1/test1.jpg", ownerId: "user1"))
.build();
final album = (util.AlbumBuilder()
// added after album shared, thus managed by adder
..addFileItem(files[0],
addedBy: "user1", addedAt: DateTime.utc(2021, 1, 2, 3, 4, 5))
..addShare("user1"))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(
id: "1", file: files[0], uidOwner: "user1", shareWith: "admin"),
util.buildShare(
id: "2", file: files[0], uidOwner: "user1", shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, []),
],
);
}
/// Query a shared album (admin -> user1), with album json shared
/// (admin -> user1, user2)
///
/// Expect: emit the file with extra share (admin -> user2)
void _testQuerySharedAlbumExtraJsonShare(String description) {
final account = util.buildAccount();
final album = (util.AlbumBuilder()..addShare("user1")).build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(id: "1", file: albumFile, shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(albumFile, [
ListAlbumShareOutlierExtraShareItem(
util.buildShare(id: "1", file: albumFile, shareWith: "user2")),
]),
]),
],
);
}
/// Query a shared album (user1 -> admin), with file added by admin not shared
/// (admin -> user1)
///
/// Expect: emit the file with missing share (admin -> user1)
void _testQuerySharedAlbumNotOwnedMissingShareToOwner(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder(ownerId: "user1")
..addFileItem(files[0])
..addShare("admin"))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(
id: "0", file: albumFile, uidOwner: "user1", shareWith: "admin"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(files[0], [
ListAlbumShareOutlierMissingShareItem("user1".toCi(), "user1"),
]),
]),
],
);
}
/// Query a shared album (user1 -> admin, user2), with file added by admin,
/// managed by admin, not shared (admin -> user2)
///
/// Expect: emit the file with missing share (admin -> user2)
void _testQuerySharedAlbumNotOwnedMissingManagedShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder(ownerId: "user1")
// added after album shared, thus managed by adder
..addFileItem(files[0], addedAt: DateTime.utc(2021, 1, 2, 3, 4, 5))
..addShare("admin")
..addShare("user2"))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(
id: "0", file: albumFile, uidOwner: "user1", shareWith: "admin"),
util.buildShare(
id: "1", file: albumFile, uidOwner: "user1", shareWith: "user2"),
util.buildShare(id: "2", file: files[0], shareWith: "user1"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(files[0], [
ListAlbumShareOutlierMissingShareItem("user2".toCi(), "user2"),
]),
]),
],
);
}
/// Query a shared album (user1 -> admin, user2), with file added by admin,
/// managed by user1, not shared (user1 -> user2)
///
/// Expect: emit empty list
void _testQuerySharedAlbumNotOwnedMissingUnmanagedShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder(ownerId: "user1")
// added before album shared, thus managed by album owner
..addFileItem(files[0], addedBy: "admin")
..addShare("admin", sharedAt: DateTime.utc(2021, 1, 2, 3, 4, 5))
..addShare("user2", sharedAt: DateTime.utc(2021, 1, 2, 3, 4, 5)))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(id: "1", file: albumFile, shareWith: "user2"),
util.buildShare(id: "2", file: files[0], shareWith: "user1"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, []),
],
);
}
/// Query a shared album (user1 -> admin, user2), with missing album json share
/// (user1 -> user2)
///
/// Expect: emit empty list
void _testQuerySharedAlbumNotOwnedMissingJsonShare(String description) {
final account = util.buildAccount();
final album = (util.AlbumBuilder(ownerId: "user1")
..addShare("admin")
..addShare("user2"))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(
id: "0", file: albumFile, uidOwner: "user1", shareWith: "admin"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, []),
],
);
}
/// Query a shared album (user1 -> admin), with file added by admin, managed by
/// admin, shared (admin -> user1, user2)
///
/// Expect: emit the file with missing share (admin -> user2)
void _testQuerySharedAlbumNotOwnedExtraManagedShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder(ownerId: "user1")
// added after album shared, thus managed by adder
..addFileItem(files[0], addedAt: DateTime.utc(2021, 1, 2, 3, 4, 5))
..addShare("admin"))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(
id: "0", file: albumFile, uidOwner: "user1", shareWith: "admin"),
util.buildShare(id: "1", file: files[0], shareWith: "user1"),
util.buildShare(id: "2", file: files[0], shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(files[0], [
ListAlbumShareOutlierExtraShareItem(
util.buildShare(id: "2", file: files[0], shareWith: "user2")),
]),
]),
],
);
}
/// Query a shared album (user1 -> admin), with file added by admin, managed by
/// user1, shared (admin -> user1, user2)
///
/// Expect: emit the file with missing share (admin -> user2)
void _testQuerySharedAlbumNotOwnedExtraUnmanagedShare(String description) {
final account = util.buildAccount();
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder(ownerId: "user1")
// added before album shared, thus managed by album owner
..addFileItem(files[0], addedBy: "admin")
..addShare("admin", sharedAt: DateTime.utc(2021, 1, 2, 3, 4, 5)))
.build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(
id: "0", file: albumFile, uidOwner: "user1", shareWith: "admin"),
util.buildShare(id: "1", file: files[0], shareWith: "user1"),
util.buildShare(id: "2", file: files[0], shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, [
ListAlbumShareOutlierItem(files[0], [
ListAlbumShareOutlierExtraShareItem(
util.buildShare(id: "2", file: files[0], shareWith: "user2")),
]),
]),
],
);
}
/// Query a shared album (user1 -> admin), with album json share
/// (user1 -> admin, user2)
///
/// Expect: emit empty list
void _testQuerySharedAlbumNotOwnedExtraJsonShare(String description) {
final account = util.buildAccount();
final album =
(util.AlbumBuilder(ownerId: "user1")..addShare("admin")).build();
final albumFile = album.albumFile!;
final shareRepo = MockShareMemoryRepo([
util.buildShare(
id: "0", file: albumFile, uidOwner: "user1", shareWith: "admin"),
util.buildShare(
id: "1", file: albumFile, uidOwner: "user1", shareWith: "user2"),
]);
final shareeRepo = MockShareeMemoryRepo([
util.buildSharee(shareWith: "user1".toCi()),
util.buildSharee(shareWith: "user2".toCi()),
]);
blocTest<ListAlbumShareOutlierBloc, ListAlbumShareOutlierBlocState>(
description,
build: () => ListAlbumShareOutlierBloc(shareRepo, shareeRepo),
act: (bloc) => bloc.add(ListAlbumShareOutlierBlocQuery(account, album)),
wait: const Duration(milliseconds: 500),
expect: () => [
ListAlbumShareOutlierBlocLoading(account, []),
ListAlbumShareOutlierBlocSuccess(account, []),
],
);
}

View file

@ -1674,6 +1674,7 @@ void _fromJsonShares() {
{
"userId": "admin",
"displayName": "admin",
"sharedAt": "2020-01-02T03:04:05.000Z",
},
],
};
@ -1727,6 +1728,7 @@ void _toRemoteJsonShares() {
<String, dynamic>{
"userId": "admin",
"displayName": "admin",
"sharedAt": "2020-01-02T03:04:05.000Z",
},
],
});
@ -1765,6 +1767,7 @@ void _toAppDbJsonShares() {
<String, dynamic>{
"userId": "admin",
"displayName": "admin",
"sharedAt": "2020-01-02T03:04:05.000Z",
},
],
});

View file

@ -105,8 +105,16 @@ class AlbumBuilder {
}
/// Add an album share
void addShare(String userId) {
shares.add(buildAlbumShare(userId: userId));
///
/// By default, the album will be shared at 2020-01-02 03:04:05
void addShare(
String userId, {
DateTime? sharedAt,
}) {
shares.add(buildAlbumShare(
userId: userId,
sharedAt: sharedAt,
));
}
static fileItemsOf(Album album) =>
@ -170,10 +178,12 @@ String buildAlbumFilePath(
AlbumShare buildAlbumShare({
required String userId,
String? displayName,
DateTime? sharedAt,
}) =>
AlbumShare(
userId: userId.toCi(),
displayName: displayName ?? userId,
sharedAt: sharedAt ?? DateTime.utc(2020, 1, 2, 3, 4, 5),
);
/// Build a mock [File] pointing to a JPEG image file

View file

@ -22,6 +22,7 @@ void main() {
group("AddToAlbum", () {
test("file", _addFile);
test("ignore existing file", _addExistingFile);
group("shared album (owned)", () {
test("file", _addFileToSharedAlbumOwned);
test("file owned by user", _addFileOwnedByUserToSharedAlbumOwned);
@ -94,6 +95,88 @@ Future<void> _addFile() async {
);
}
/// Add a [File], already included in the [Album], to an [Album]
///
/// Expect: file not added to album
Future<void> _addExistingFile() async {
final account = util.buildAccount();
final pref = Pref.scoped(PrefMemoryProvider());
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final album = (util.AlbumBuilder()..addFileItem(files[0])).build();
final oldFile = files[0];
final newFile = files[0].copyWith();
final albumFile = album.albumFile!;
final appDb = MockAppDb();
await appDb.use((db) async {
final transaction = db.transaction(AppDb.fileDbStoreName, idbModeReadWrite);
final store = transaction.objectStore(AppDb.fileDbStoreName);
await store.put(AppDbFileDbEntry.fromFile(account, files[0]).toJson(),
AppDbFileDbEntry.toPrimaryKey(account, files[0]));
});
final albumRepo = MockAlbumMemoryRepo([album]);
final shareRepo = MockShareRepo();
await AddToAlbum(albumRepo, shareRepo, appDb, pref)(
account,
albumRepo.findAlbumByPath(albumFile.path),
[
AlbumFileItem(
addedBy: "admin".toCi(),
addedAt: DateTime.utc(2020, 1, 2, 3, 4, 5),
file: newFile,
),
],
);
expect(
albumRepo.albums
.map((e) => e.copyWith(
// we need to set a known value to lastUpdated
lastUpdated: OrNull(DateTime.utc(2020, 1, 2, 3, 4, 5)),
))
.toList(),
[
Album(
lastUpdated: DateTime.utc(2020, 1, 2, 3, 4, 5),
name: "test",
provider: AlbumStaticProvider(
items: [
AlbumFileItem(
addedBy: "admin".toCi(),
addedAt: DateTime.utc(2020, 1, 2, 3, 4, 5),
file: files[0],
),
],
latestItemTime: DateTime.utc(2020, 1, 2, 3, 4, 5),
),
coverProvider: AlbumAutoCoverProvider(coverFile: files[0]),
sortProvider: const AlbumNullSortProvider(),
albumFile: albumFile,
),
],
);
// when there's a conflict, it's guaranteed that the original file in the
// album is kept and the incoming file dropped
expect(
identical(
AlbumStaticProvider.of(albumRepo.albums[0])
.items
.whereType<AlbumFileItem>()
.first
.file,
oldFile),
true);
expect(
identical(
AlbumStaticProvider.of(albumRepo.albums[0])
.items
.whereType<AlbumFileItem>()
.first
.file,
newFile),
false);
}
/// Add a file to a shared album (admin -> user1)
///
/// Expect: a new share (admin -> user1) is created for the file

View file

@ -1,6 +1,7 @@
import 'package:event_bus/event_bus.dart';
import 'package:kiwi/kiwi.dart';
import 'package:nc_photos/ci_string.dart';
import 'package:nc_photos/or_null.dart';
import 'package:nc_photos/use_case/share_album_with_user.dart';
import 'package:test/test.dart';
@ -35,7 +36,14 @@ Future<void> _shareWithoutFile() async {
util.buildSharee(shareWith: "user1".toCi()),
);
expect(
albumRepo.findAlbumByPath(albumFile.path).shares,
albumRepo
.findAlbumByPath(albumFile.path)
.shares
?.map((s) => s.copyWith(
// we need to set a known value to sharedAt
sharedAt: OrNull(DateTime.utc(2020, 1, 2, 3, 4, 5)),
))
.toList(),
[util.buildAlbumShare(userId: "user1")],
);
expect(
@ -65,7 +73,14 @@ Future<void> _shareWithFile() async {
util.buildSharee(shareWith: "user1".toCi()),
);
expect(
albumRepo.findAlbumByPath(albumFile.path).shares,
albumRepo
.findAlbumByPath(albumFile.path)
.shares
?.map((s) => s.copyWith(
// we need to set a known value to sharedAt
sharedAt: OrNull(DateTime.utc(2020, 1, 2, 3, 4, 5)),
))
.toList(),
[util.buildAlbumShare(userId: "user1")],
);
expect(
@ -97,7 +112,14 @@ Future<void> _shareWithFileOwnedByUser() async {
util.buildSharee(shareWith: "user1".toCi()),
);
expect(
albumRepo.findAlbumByPath(albumFile.path).shares,
albumRepo
.findAlbumByPath(albumFile.path)
.shares
?.map((s) => s.copyWith(
// we need to set a known value to sharedAt
sharedAt: OrNull(DateTime.utc(2020, 1, 2, 3, 4, 5)),
))
.toList(),
[util.buildAlbumShare(userId: "user1")],
);
expect(
@ -127,7 +149,14 @@ Future<void> _shareSharedAlbum() async {
util.buildSharee(shareWith: "user2".toCi()),
);
expect(
albumRepo.findAlbumByPath(albumFile.path).shares,
albumRepo
.findAlbumByPath(albumFile.path)
.shares
?.map((s) => s.copyWith(
// we need to set a known value to sharedAt
sharedAt: OrNull(DateTime.utc(2020, 1, 2, 3, 4, 5)),
))
.toList(),
[
util.buildAlbumShare(userId: "user1"),
util.buildAlbumShare(userId: "user2"),