Skip to content

Commit 2a07f37

Browse files
authored
Поправил удаление фотографий (#251)
- Теперь при удалении фотографий для площадки/мероприятия наш список фото создается заново с учетом корректировки идентификаторов - Судя по всему, после каждого удаления фотографии на сервере там происходит обновление идентификаторов в коллекции фото: всем фоткам присваиваются номера, начиная с `1` - Добавил `unit`-тесты
1 parent e0bfbc6 commit 2a07f37

File tree

8 files changed

+96
-9
lines changed

8 files changed

+96
-9
lines changed

SwiftUI-WorkoutApp.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@
846846
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
847847
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
848848
CODE_SIGN_STYLE = Automatic;
849-
CURRENT_PROJECT_VERSION = 6;
849+
CURRENT_PROJECT_VERSION = 7;
850850
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
851851
DEVELOPMENT_TEAM = CR68PP2Z3F;
852852
ENABLE_PREVIEWS = YES;
@@ -896,7 +896,7 @@
896896
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
897897
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
898898
CODE_SIGN_STYLE = Automatic;
899-
CURRENT_PROJECT_VERSION = 6;
899+
CURRENT_PROJECT_VERSION = 7;
900900
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
901901
DEVELOPMENT_TEAM = CR68PP2Z3F;
902902
ENABLE_PREVIEWS = YES;

SwiftUI-WorkoutApp/Libraries/SWModels/Sources/SWModels/EventResponse.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ public extension EventResponse {
165165
set { photosOptional = newValue }
166166
}
167167

168+
func removePhotoById(_ id: Int) -> [Photo] {
169+
PhotoRemover(initialPhotos: photos, removeId: id).photosAfterRemoval
170+
}
171+
168172
var hasParticipants: Bool { !participants.isEmpty }
169173

170174
/// Список участников мероприятия

SwiftUI-WorkoutApp/Libraries/SWModels/Sources/SWModels/Park.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,20 +156,24 @@ public struct Park: Codable, Identifiable, Hashable, Sendable {
156156
}
157157

158158
public struct Photo: Codable, Identifiable, Hashable, Sendable {
159-
public let id: Int
159+
public var id: String {
160+
"\(serverId)-\(stringURL ?? "")"
161+
}
162+
163+
public let serverId: Int
160164
public let stringURL: String?
161165

162166
public var imageURL: URL? {
163167
stringURL.queryAllowedURL
164168
}
165169

166170
public enum CodingKeys: String, CodingKey {
167-
case id
171+
case serverId = "id"
168172
case stringURL = "photo"
169173
}
170174

171-
public init(id: Int, stringURL: String? = nil) {
172-
self.id = id
175+
public init(id: Int, stringURL: String?) {
176+
self.serverId = id
173177
self.stringURL = stringURL
174178
}
175179
}
@@ -208,6 +212,10 @@ public extension Park {
208212
set { photosOptional = newValue }
209213
}
210214

215+
func removePhotoById(_ id: Int) -> [Photo] {
216+
PhotoRemover(initialPhotos: photos, removeId: id).photosAfterRemoval
217+
}
218+
211219
var hasComments: Bool { !comments.isEmpty }
212220

213221
var comments: [CommentResponse] {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Foundation
2+
3+
/// Удаляет фото по идентификатору и составляет актуальный список фото
4+
struct PhotoRemover {
5+
private let initialPhotos: [Photo]
6+
private let removeId: Int
7+
8+
/// Инициализатор
9+
/// - Parameters:
10+
/// - initialPhotos: Первоначальный массив фотографий
11+
/// - removeId: Идентификатор фотографии для удаления
12+
init(initialPhotos: [Photo], removeId: Int) {
13+
self.initialPhotos = initialPhotos
14+
self.removeId = removeId
15+
}
16+
17+
/// Актуальный список фотографий после процедуры удаления
18+
///
19+
/// На сервере идентификаторы фотографий начинаются с цифры `1`,
20+
/// при изменении набора фотографий их идентификаторы тоже обновляются
21+
var photosAfterRemoval: [Photo] {
22+
initialPhotos
23+
.filter { $0.serverId != removeId }
24+
.enumerated()
25+
.map { index, photo in
26+
Photo(id: index + 1, stringURL: photo.stringURL)
27+
}
28+
}
29+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
@testable import SWModels
2+
import Testing
3+
4+
struct PhotoRemoverTests {
5+
@Test
6+
func removesCorrectPhoto() {
7+
let photos = makeTestPhotos(count: 4)
8+
let removeId = 2
9+
let photoRemover = PhotoRemover(initialPhotos: photos, removeId: removeId)
10+
let expectedPhotos = [
11+
Photo(id: 1, stringURL: "http://example.com/photo1.jpg"),
12+
Photo(id: 2, stringURL: "http://example.com/photo3.jpg"),
13+
Photo(id: 3, stringURL: "http://example.com/photo4.jpg")
14+
]
15+
#expect(photoRemover.photosAfterRemoval == expectedPhotos)
16+
}
17+
18+
@Test
19+
func noPhotosRemoved_wrongId() {
20+
let photos = makeTestPhotos(count: 3)
21+
let removeId = 4
22+
let photoRemover = PhotoRemover(initialPhotos: photos, removeId: removeId)
23+
let expectedPhotos = [
24+
Photo(id: 1, stringURL: "http://example.com/photo1.jpg"),
25+
Photo(id: 2, stringURL: "http://example.com/photo2.jpg"),
26+
Photo(id: 3, stringURL: "http://example.com/photo3.jpg")
27+
]
28+
#expect(photoRemover.photosAfterRemoval == expectedPhotos)
29+
}
30+
31+
@Test
32+
func emptyPhotosBeforeAndAfter() {
33+
let photos = [Photo]()
34+
let removeId = 1
35+
let photoRemover = PhotoRemover(initialPhotos: photos, removeId: removeId)
36+
let expectedPhotos = [Photo]()
37+
#expect(photoRemover.photosAfterRemoval == expectedPhotos)
38+
}
39+
}
40+
41+
private func makeTestPhotos(count: Int) -> [Photo] {
42+
Array(0 ..< count).map { id in
43+
let serverId = id + 1
44+
return Photo(id: serverId, stringURL: "http://example.com/photo\(serverId).jpg")
45+
}
46+
}

SwiftUI-WorkoutApp/Screens/Common/PhotoSection/PhotoSectionView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ private extension PhotoSectionView {
9292
ResizableCachedImage(
9393
url: photo.imageURL,
9494
didTapImage: { uiImage in
95-
fullscreenImageInfo = .init(uiImage: uiImage, id: photo.id)
95+
fullscreenImageInfo = .init(uiImage: uiImage, id: photo.serverId)
9696
}
9797
)
9898
.scaledToFill()

SwiftUI-WorkoutApp/Screens/Events/EventDetailsView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ private extension EventDetailsView {
365365
if try await SWClient(with: defaults).deletePhoto(
366366
from: .event(.init(containerID: event.id, photoID: id))
367367
) {
368-
event.photos.removeAll(where: { $0.id == id })
368+
event.photos = event.removePhotoById(id)
369369
}
370370
} catch {
371371
setupErrorAlert(ErrorFilter.message(from: error))

SwiftUI-WorkoutApp/Screens/Parks/ParkDetailScreen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ private extension ParkDetailScreen {
339339
if try await SWClient(with: defaults).deletePhoto(
340340
from: .park(.init(containerID: park.id, photoID: id))
341341
) {
342-
park.photos.removeAll(where: { $0.id == id })
342+
park.photos = park.removePhotoById(id)
343343
}
344344
} catch {
345345
process(error)

0 commit comments

Comments
 (0)