From 32431096f5666562f42e2aa1b74c06a2e961eaeb Mon Sep 17 00:00:00 2001 From: Bryan Montz Date: Sat, 13 May 2023 09:20:01 -0500 Subject: [PATCH] add tests for ProfileDatabase --- damus.xcodeproj/project.pbxproj | 4 + damusTests/ProfileDatabaseTests.swift | 117 ++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 damusTests/ProfileDatabaseTests.swift diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj index fb547596..91ddb701 100644 --- a/damus.xcodeproj/project.pbxproj +++ b/damus.xcodeproj/project.pbxproj @@ -259,6 +259,7 @@ 50088DA129E8271A008A1FDF /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50088DA029E8271A008A1FDF /* WebSocket.swift */; }; 501F8C802A0220E1001AFC1D /* KeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C7F2A0220E1001AFC1D /* KeychainStorage.swift */; }; 501F8C822A0224EB001AFC1D /* KeychainStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C812A0224EB001AFC1D /* KeychainStorageTests.swift */; }; + 5019CADD2A0FB0A9000069E1 /* ProfileDatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CADC2A0FB0A9000069E1 /* ProfileDatabaseTests.swift */; }; 501F8C5529FF5EF6001AFC1D /* PersistedProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C5429FF5EF6001AFC1D /* PersistedProfile.swift */; }; 501F8C5829FF5FC5001AFC1D /* Damus.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C5629FF5FC5001AFC1D /* Damus.xcdatamodeld */; }; 501F8C5A29FF70F5001AFC1D /* ProfileDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C5929FF70F5001AFC1D /* ProfileDatabase.swift */; }; @@ -685,6 +686,7 @@ 50088DA029E8271A008A1FDF /* WebSocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocket.swift; sourceTree = ""; }; 501F8C7F2A0220E1001AFC1D /* KeychainStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStorage.swift; sourceTree = ""; }; 501F8C812A0224EB001AFC1D /* KeychainStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStorageTests.swift; sourceTree = ""; }; + 5019CADC2A0FB0A9000069E1 /* ProfileDatabaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileDatabaseTests.swift; sourceTree = ""; }; 501F8C5429FF5EF6001AFC1D /* PersistedProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistedProfile.swift; sourceTree = ""; }; 501F8C5729FF5FC5001AFC1D /* Damus.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Damus.xcdatamodel; sourceTree = ""; }; 501F8C5929FF70F5001AFC1D /* ProfileDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileDatabase.swift; sourceTree = ""; }; @@ -1275,6 +1277,7 @@ 4CB883AD2976FA9300DC99E7 /* FormatTests.swift */, 3A3040EC29A5CB86008A0F29 /* ReplyDescriptionTests.swift */, 3A3040EE29A8FEE9008A0F29 /* EventDetailBarTests.swift */, + 5019CADC2A0FB0A9000069E1 /* ProfileDatabaseTests.swift */, 3A3040F229A91366008A0F29 /* ProfileViewTests.swift */, 3A30410029AB12AA008A0F29 /* EventGroupViewTests.swift */, 4C8D00D329E3C5D40036AF10 /* NIP19Tests.swift */, @@ -1833,6 +1836,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5019CADD2A0FB0A9000069E1 /* ProfileDatabaseTests.swift in Sources */, 3A3040ED29A5CB86008A0F29 /* ReplyDescriptionTests.swift in Sources */, 4C8D00D429E3C5D40036AF10 /* NIP19Tests.swift in Sources */, 3A30410129AB12AA008A0F29 /* EventGroupViewTests.swift in Sources */, diff --git a/damusTests/ProfileDatabaseTests.swift b/damusTests/ProfileDatabaseTests.swift new file mode 100644 index 00000000..31fe4b1b --- /dev/null +++ b/damusTests/ProfileDatabaseTests.swift @@ -0,0 +1,117 @@ +// +// ProfileDatabaseTests.swift +// damusTests +// +// Created by Bryan Montz on 5/13/23. +// + +import XCTest +@testable import damus + +class ProfileDatabaseTests: XCTestCase { + + static let cache_url = (FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.appendingPathComponent("test-profiles"))! + let database = ProfileDatabase(cache_url: ProfileDatabaseTests.cache_url) + + override func tearDownWithError() throws { + // This method is called after the invocation of each test method in the class. + try database.remove_all_profiles() + } + + var test_profile: Profile { + Profile(name: "test-name", + display_name: "test-display-name", + about: "test-about", + picture: "test-picture", + banner: "test-banner", + website: "test-website", + lud06: "test-lud06", + lud16: "test-lud16", + nip05: "test-nip05") + } + + func testStoreAndRetrieveProfile() throws { + let id = "test-id" + + let profile = test_profile + + // make sure it's not there yet + XCTAssertNil(database.get(id: id)) + + // store the profile + try database.upsert(id: id, profile: profile, last_update: .now) + + // read the profile out of the database + let retrievedProfile = try XCTUnwrap(database.get(id: id)) + + XCTAssertEqual(profile.name, retrievedProfile.name) + XCTAssertEqual(profile.display_name, retrievedProfile.display_name) + XCTAssertEqual(profile.about, retrievedProfile.about) + XCTAssertEqual(profile.picture, retrievedProfile.picture) + XCTAssertEqual(profile.banner, retrievedProfile.banner) + XCTAssertEqual(profile.website, retrievedProfile.website) + XCTAssertEqual(profile.lud06, retrievedProfile.lud06) + XCTAssertEqual(profile.lud16, retrievedProfile.lud16) + XCTAssertEqual(profile.nip05, retrievedProfile.nip05) + } + + func testRejectOutdatedProfile() throws { + let id = "test-id" + + // store a profile + let profile = test_profile + let profile_last_updated = Date.now + try database.upsert(id: id, profile: profile, last_update: profile_last_updated) + + // try to store a profile with the same id but the last_update date is older than the previously stored profile + let outdatedProfile = test_profile + let outdated_last_updated = profile_last_updated.addingTimeInterval(-60) + + XCTAssertThrowsError(try database.upsert(id: id, profile: outdatedProfile, last_update: outdated_last_updated)) { error in + XCTAssertEqual(error as? ProfileDatabaseError, ProfileDatabaseError.outdated_input) + } + } + + func testUpdateExistingProfile() throws { + let id = "test-id" + + // store a profile + let profile = test_profile + let profile_last_update = Date.now + try database.upsert(id: id, profile: profile, last_update: profile_last_update) + + // update the same profile + let updated_profile = test_profile + updated_profile.nip05 = "updated-nip05" + let updated_profile_last_update = profile_last_update.addingTimeInterval(60) + try database.upsert(id: id, profile: updated_profile, last_update: updated_profile_last_update) + + // retrieve the profile and make sure it was updated + let retrieved_profile = database.get(id: id) + XCTAssertEqual(retrieved_profile?.nip05, "updated-nip05") + } + + func testStoreMultipleAndRemoveAllProfiles() throws { + XCTAssertEqual(database.count, 0) + + // store a profile + let id = "test-id" + let profile = test_profile + let profile_last_update = Date.now + try database.upsert(id: id, profile: profile, last_update: profile_last_update) + + XCTAssertEqual(database.count, 1) + + // store another profile + let id2 = "test-id-2" + let profile2 = test_profile + let profile_last_update2 = Date.now + try database.upsert(id: id2, profile: profile2, last_update: profile_last_update2) + + XCTAssertEqual(database.count, 2) + + try database.remove_all_profiles() + + XCTAssertEqual(database.count, 0) + } +}