diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj index 3769bb59..ad962ff8 100644 --- a/damus.xcodeproj/project.pbxproj +++ b/damus.xcodeproj/project.pbxproj @@ -430,6 +430,9 @@ BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */; }; D2277EEA2A089BD5006C3807 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2277EE92A089BD5006C3807 /* Router.swift */; }; D71DC1EC2A9129C3006E207C /* PostViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71DC1EB2A9129C3006E207C /* PostViewTests.swift */; }; + D72A2D022AD9C136002AFF62 /* EventViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A2CFF2AD9B66B002AFF62 /* EventViewTests.swift */; }; + D72A2D052AD9C1B5002AFF62 /* MockDamusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A2D042AD9C1B5002AFF62 /* MockDamusState.swift */; }; + D72A2D072AD9C1FB002AFF62 /* MockProfiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A2D062AD9C1FB002AFF62 /* MockProfiles.swift */; }; D7315A2A2ACDF3B70036E30A /* DamusCacheManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315A292ACDF3B70036E30A /* DamusCacheManager.swift */; }; D7315A2C2ACDF4DA0036E30A /* DamusCacheManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315A2B2ACDF4DA0036E30A /* DamusCacheManagerTests.swift */; }; D723C38E2AB8D83400065664 /* ContentFilters.swift in Sources */ = {isa = PBXBuildFile; fileRef = D723C38D2AB8D83400065664 /* ContentFilters.swift */; }; @@ -1128,6 +1131,9 @@ D2277EE92A089BD5006C3807 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; D71DC1EB2A9129C3006E207C /* PostViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewTests.swift; sourceTree = ""; }; D723C38D2AB8D83400065664 /* ContentFilters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentFilters.swift; sourceTree = ""; }; + D72A2CFF2AD9B66B002AFF62 /* EventViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventViewTests.swift; sourceTree = ""; }; + D72A2D042AD9C1B5002AFF62 /* MockDamusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDamusState.swift; sourceTree = ""; }; + D72A2D062AD9C1FB002AFF62 /* MockProfiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockProfiles.swift; sourceTree = ""; }; D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentViewTests.swift; sourceTree = ""; }; D7870BC02AC4750B0080BA88 /* MentionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionView.swift; sourceTree = ""; }; D7870BC22AC47EBC0080BA88 /* EventLoaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventLoaderView.swift; sourceTree = ""; }; @@ -2155,6 +2161,7 @@ 4CE6DEF627F7A08200C66700 /* damusTests */ = { isa = PBXGroup; children = ( + D72A2D032AD9C165002AFF62 /* Mocking */, 4C9B0DEC2A65A74000CBDA21 /* Util */, 4C0C03962A61E2670098B3B8 /* Fixtures */, 4C7D097D2A0C58B900943473 /* WalletConnectTests.swift */, @@ -2185,6 +2192,7 @@ 4C684A562A7FFAE6005E6031 /* UrlTests.swift */, D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */, D71DC1EB2A9129C3006E207C /* PostViewTests.swift */, + D72A2CFF2AD9B66B002AFF62 /* EventViewTests.swift */, D7315A2B2ACDF4DA0036E30A /* DamusCacheManagerTests.swift */, ); path = damusTests; @@ -2313,12 +2321,13 @@ path = Camera; sourceTree = ""; }; - BA3759952ABCCF360018D73B /* Camera */ = { + D72A2D032AD9C165002AFF62 /* Mocking */ = { isa = PBXGroup; children = ( - BA3759962ABCCF360018D73B /* CameraPreview.swift */, + D72A2D042AD9C1B5002AFF62 /* MockDamusState.swift */, + D72A2D062AD9C1FB002AFF62 /* MockProfiles.swift */, ); - path = Camera; + path = Mocking; sourceTree = ""; }; F71694E82A66221E001F4053 /* Onboarding */ = { @@ -2975,12 +2984,14 @@ 3A30410129AB12AA008A0F29 /* EventGroupViewTests.swift in Sources */, 501F8C822A0224EB001AFC1D /* KeychainStorageTests.swift in Sources */, 3ACBCB78295FE5C70037388A /* TimeAgoTests.swift in Sources */, + D72A2D072AD9C1FB002AFF62 /* MockProfiles.swift in Sources */, 4C4F14A72A2A61A30045A0B9 /* NostrScriptTests.swift in Sources */, D78525252A7B2EA4002FA637 /* NoteContentViewTests.swift in Sources */, 4C3EA67B28FF7B3900C48A62 /* InvoiceTests.swift in Sources */, 4C363A9E2828A822006E126D /* ReplyTests.swift in Sources */, 4C7D097E2A0C58B900943473 /* WalletConnectTests.swift in Sources */, 4CB883AA297612FF00DC99E7 /* ZapTests.swift in Sources */, + D72A2D022AD9C136002AFF62 /* EventViewTests.swift in Sources */, 4CB8839A297322D200DC99E7 /* DMTests.swift in Sources */, D7315A2C2ACDF4DA0036E30A /* DamusCacheManagerTests.swift in Sources */, 4C9054852A6AEAA000811EEC /* NdbTests.swift in Sources */, @@ -2988,6 +2999,7 @@ F944F56E29EA9CCC0067B3BF /* DamusParseContentTests.swift in Sources */, 3A5E47C72A4A76C800C0D090 /* TrieTests.swift in Sources */, 4CB883AE2976FA9300DC99E7 /* FormatTests.swift in Sources */, + D72A2D052AD9C1B5002AFF62 /* MockDamusState.swift in Sources */, 4C363AA02828A8DD006E126D /* LikeTests.swift in Sources */, 4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */, 50A50A8D29A09E1C00C01BE7 /* RequestTests.swift in Sources */, diff --git a/damusTests/EventViewTests.swift b/damusTests/EventViewTests.swift new file mode 100644 index 00000000..ccd3c356 --- /dev/null +++ b/damusTests/EventViewTests.swift @@ -0,0 +1,46 @@ +// +// EventViewTests.swift +// damusTests +// +// Created by Daniel D’Aquino on 2023-10-13. +// + +import Foundation +import XCTest +import SnapshotTesting +import SwiftUI +@testable import damus + +final class EventViewTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testBasicEventViewLayout() { + let test_mock_damus_state = generate_test_damus_state( + mock_profile_info: [ + // Manually mock some profile info so that we have a more realistic-looking note + jack_keypair.pubkey: Profile( + name: "jack", + display_name: "Jack Dorsey" + ) + ] + ) + let test_note = NostrEvent( + content: "Nostr is the super app. Because it’s actually an ecosystem of apps, all of which make each other better. People haven’t grasped that yet. They will when it’s more accessible and onboarding is more straightforward and intuitive.", + keypair: jack_keypair, + createdAt: UInt32(Date.init(timeIntervalSinceNow: -60).timeIntervalSince1970) + )! + + let eventViewTest = EventView(damus: test_mock_damus_state, event: test_note).padding() + let hostView = UIHostingController(rootView: eventViewTest) + + // Run snapshot check + assertSnapshot(matching: hostView, as: .image(on: .iPhone13(.portrait))) + } +} diff --git a/damusTests/Mocking/MockDamusState.swift b/damusTests/Mocking/MockDamusState.swift new file mode 100644 index 00000000..9d49c9ab --- /dev/null +++ b/damusTests/Mocking/MockDamusState.swift @@ -0,0 +1,66 @@ +// +// MockDamusState.swift +// damusTests +// +// Created by Daniel D’Aquino on 2023-10-13. +// + +import Foundation +@testable import damus + +// Generates a test damus state with configurable mock parameters +func generate_test_damus_state( + mock_profile_info: [Pubkey: Profile]? +) -> DamusState { + // Create a unique temporary directory + var tempDir: String! + do { + let fileManager = FileManager.default + let temp = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString) + try fileManager.createDirectory(at: temp, withIntermediateDirectories: true, attributes: nil) + tempDir = temp.absoluteString + } catch { + tempDir = "." + } + + print("opening \(tempDir!)") + let ndb = Ndb(path: tempDir)! + let our_pubkey = test_pubkey + let pool = RelayPool(ndb: ndb) + let settings = UserSettingsStore() + + let profiles: Profiles = { + guard let mock_profile_info, let profiles: Profiles = MockProfiles(mocked_profiles: mock_profile_info, ndb: ndb) else { + return Profiles.init(ndb: ndb) + } + return profiles + }() + + let damus = DamusState(pool: pool, + keypair: test_keypair, + likes: .init(our_pubkey: our_pubkey), + boosts: .init(our_pubkey: our_pubkey), + contacts: .init(our_pubkey: our_pubkey), + profiles: profiles, + dms: .init(our_pubkey: our_pubkey), + previews: .init(), + zaps: .init(our_pubkey: our_pubkey), + lnurls: .init(), + settings: settings, + relay_filters: .init(our_pubkey: our_pubkey), + relay_model_cache: .init(), + drafts: .init(), + events: .init(ndb: ndb), + bookmarks: .init(pubkey: our_pubkey), + postbox: .init(pool: pool), + bootstrap_relays: .init(), + replies: .init(our_pubkey: our_pubkey), + muted_threads: .init(keypair: test_keypair), + wallet: .init(settings: settings), + nav: .init(), + music: .init(onChange: {_ in }), + video: .init(), + ndb: ndb) + + return damus +} diff --git a/damusTests/Mocking/MockProfiles.swift b/damusTests/Mocking/MockProfiles.swift new file mode 100644 index 00000000..591ba2f6 --- /dev/null +++ b/damusTests/Mocking/MockProfiles.swift @@ -0,0 +1,28 @@ +// +// MockProfiles.swift +// damusTests +// +// Created by Daniel D’Aquino on 2023-10-13. +// + +import Foundation +@testable import damus + +// A Mockable `Profiles` class that can be used for testing. +// Note: Not all methods are mocked. You might need to implement a method depending on the test you are writing. +class MockProfiles: Profiles { + var mocked_profiles: [Pubkey: Profile] = [:] + var ndb: Ndb + + init?(mocked_profiles: [Pubkey : Profile], ndb: Ndb) { + self.mocked_profiles = mocked_profiles + self.ndb = ndb + super.init(ndb: ndb) + } + + override func lookup(id: Pubkey) -> NdbTxn { + return NdbTxn(ndb: self.ndb) { txn in + return self.mocked_profiles[id] + } + } +} diff --git a/damusTests/__Snapshots__/EventViewTests/testBasicEventViewLayout.1.png b/damusTests/__Snapshots__/EventViewTests/testBasicEventViewLayout.1.png new file mode 100644 index 00000000..51454c1c Binary files /dev/null and b/damusTests/__Snapshots__/EventViewTests/testBasicEventViewLayout.1.png differ