Merge improved mute functionality from Charlie
This merge adds a bunch of new features from charlie's work on the new mutelist changes: - Muted words - Mute performance optimizations - New mute list UI I needed to make a few changes to fix the tests in this merge. Otherwise it seems to work ok! Thank to Charlie for getting all of this working after many rounds of review! * branch `mute` of https://github.com/damus-io/damus: mute: fix bug with duplicate Indefinite items in MuteDurationMenu mute: fix mute hashtag from search view if no existing mutelist mute: integrate new MutelistManager mute: adding MutelistManager.swift mute: add maybe_get_content function to NdbNote mute: fix bug where mutes can't be added without existing mutelist mute: fix issue with not being able to change mute duration mute: don't mutate string when adding hashtag mute: implement fast MuteItem decoder tags: add u64 decoding function mute: migrating muted_threads to new mute list mute: adding ability to mute hashtag from SearchView mute: updating UI to support new mute list mute: adding filtering support for MuteItem events mute: receiving New Mute List Type mute: migrate Lists.swift to use new MuteItem mute: add new UI views for new mute list mute: adding new structs/enums for new mute list Changelog-Added: Add ability to mute words, add new mutelist interface (Charlie)
This commit is contained in:
@@ -23,15 +23,13 @@ final class ListTests: XCTestCase {
|
||||
let pubkey = test_keypair_full.pubkey
|
||||
let to_mute = test_pubkey
|
||||
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
|
||||
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .pubkey(to_mute))!
|
||||
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .user(to_mute, nil))!
|
||||
|
||||
XCTAssertEqual(mutelist.pubkey, pubkey)
|
||||
XCTAssertEqual(mutelist.content, "")
|
||||
XCTAssertEqual(mutelist.tags.count, 2)
|
||||
XCTAssertEqual(mutelist.tags[0][0].string(), "d")
|
||||
XCTAssertEqual(mutelist.tags[0][1].string(), "mute")
|
||||
XCTAssertEqual(mutelist.tags[1][0].string(), "p")
|
||||
XCTAssertEqual(mutelist.tags[1][1].string(), to_mute.hex())
|
||||
XCTAssertEqual(mutelist.tags.count, 1)
|
||||
XCTAssertEqual(mutelist.tags[0][0].string(), "p")
|
||||
XCTAssertEqual(mutelist.tags[0][1].string(), to_mute.hex())
|
||||
}
|
||||
|
||||
func testCreateAndRemoveMuteList() throws {
|
||||
@@ -39,14 +37,12 @@ final class ListTests: XCTestCase {
|
||||
let pubkey = test_keypair_full.pubkey
|
||||
let to_mute = test_pubkey
|
||||
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
|
||||
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .pubkey(to_mute))!
|
||||
let new = remove_from_mutelist(keypair: keypair, prev: mutelist, to_remove: .pubkey(to_mute))!
|
||||
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .user(to_mute, nil))!
|
||||
let new = remove_from_mutelist(keypair: keypair, prev: mutelist, to_remove: .user(to_mute, nil))!
|
||||
|
||||
XCTAssertEqual(new.pubkey, pubkey)
|
||||
XCTAssertEqual(new.content, "")
|
||||
XCTAssertEqual(new.tags.count, 1)
|
||||
XCTAssertEqual(new.tags[0][0].string(), "d")
|
||||
XCTAssertEqual(new.tags[0][1].string(), "mute")
|
||||
XCTAssertEqual(new.tags.count, 0)
|
||||
}
|
||||
|
||||
func testAddToExistingMutelist() throws {
|
||||
@@ -55,17 +51,25 @@ final class ListTests: XCTestCase {
|
||||
let to_mute = test_pubkey
|
||||
let to_mute_2 = test_pubkey_2
|
||||
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
|
||||
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .pubkey(to_mute))!
|
||||
let new = create_or_update_mutelist(keypair: keypair, mprev: mutelist, to_add: .pubkey(to_mute_2))!
|
||||
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .user(to_mute, nil))!
|
||||
let new = create_or_update_mutelist(keypair: keypair, mprev: mutelist, to_add: .user(to_mute_2, nil))!
|
||||
|
||||
XCTAssertEqual(new.pubkey, pubkey)
|
||||
XCTAssertEqual(new.content, "")
|
||||
XCTAssertEqual(new.tags.count, 3)
|
||||
XCTAssertEqual(new.tags[0][0].string(), "d")
|
||||
XCTAssertEqual(new.tags[0][1].string(), "mute")
|
||||
XCTAssertEqual(new.tags.count, 2)
|
||||
XCTAssertEqual(new.tags[0][0].string(), "p")
|
||||
XCTAssertEqual(new.tags[1][0].string(), "p")
|
||||
XCTAssertEqual(new.tags[1][1].string(), to_mute.hex())
|
||||
XCTAssertEqual(new.tags[2][0].string(), "p")
|
||||
XCTAssertEqual(new.tags[2][1].string(), to_mute_2.hex())
|
||||
// This test failed once out of like 10 tries, due to the tags being in the incorrect order. So I decided to put the elements in an array and sort it. That way if the mutelist tags aren't in the expected order it won't fail the test.
|
||||
XCTAssertEqual([new.tags[0][1].string(), new.tags[1][1].string()].sorted(), [to_mute.hex(), to_mute_2.hex()].sorted())
|
||||
}
|
||||
|
||||
func testAddToExistingMutelistShouldNotOverrideContent() throws {
|
||||
let privkey = test_keypair_full.privkey
|
||||
let pubkey = test_keypair_full.pubkey
|
||||
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
|
||||
let mutelist = NostrEvent(content: "random", keypair: keypair.to_keypair(), kind: NostrKind.mute_list.rawValue, tags: [])
|
||||
let new = create_or_update_mutelist(keypair: keypair, mprev: mutelist, to_add: .user(test_pubkey, nil))!
|
||||
|
||||
XCTAssertEqual(new.content, "random")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ final class LongPostTests: XCTestCase {
|
||||
XCTAssertEqual(subid, "subid")
|
||||
XCTAssertTrue(ev.should_show_event)
|
||||
XCTAssertTrue(!ev.too_big)
|
||||
XCTAssertTrue(should_show_event(keypair: test_keypair, hellthreads: test_damus_state.muted_threads, contacts: contacts, ev: ev))
|
||||
XCTAssertTrue(should_show_event(state: test_damus_state, ev: ev))
|
||||
XCTAssertTrue(validate_event(ev: ev) == .ok )
|
||||
}
|
||||
|
||||
|
||||
@@ -25,11 +25,12 @@ func generate_test_damus_state(
|
||||
return profiles
|
||||
}()
|
||||
|
||||
let mutelist_manager = MutelistManager()
|
||||
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),
|
||||
contacts: .init(our_pubkey: our_pubkey), mutelist_manager: mutelist_manager,
|
||||
profiles: profiles,
|
||||
dms: .init(our_pubkey: our_pubkey),
|
||||
previews: .init(),
|
||||
@@ -44,7 +45,6 @@ func generate_test_damus_state(
|
||||
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 }),
|
||||
|
||||
58
damusTests/Models/MuteItemTests.swift
Normal file
58
damusTests/Models/MuteItemTests.swift
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// MuteItemTests.swift
|
||||
// damusTests
|
||||
//
|
||||
// Created by Charlie Fish on 1/14/24.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import damus
|
||||
|
||||
class MuteItemTests: 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.
|
||||
}
|
||||
|
||||
// MARK: - `is_expired`
|
||||
func test_hashtag_is_expired() throws {
|
||||
XCTAssertTrue(MuteItem.hashtag(Hashtag(hashtag: "test"), Date(timeIntervalSince1970: 0)).is_expired())
|
||||
XCTAssertTrue(MuteItem.hashtag(Hashtag(hashtag: "test"), .distantPast).is_expired())
|
||||
XCTAssertFalse(MuteItem.hashtag(Hashtag(hashtag: "test"), .distantFuture).is_expired())
|
||||
}
|
||||
func test_user_is_expired() throws {
|
||||
XCTAssertTrue(MuteItem.user(test_pubkey, Date(timeIntervalSince1970: 0)).is_expired())
|
||||
XCTAssertTrue(MuteItem.user(test_pubkey, .distantPast).is_expired())
|
||||
XCTAssertFalse(MuteItem.user(test_pubkey, .distantFuture).is_expired())
|
||||
}
|
||||
func test_word_is_expired() throws {
|
||||
XCTAssertTrue(MuteItem.word("test", Date(timeIntervalSince1970: 0)).is_expired())
|
||||
XCTAssertTrue(MuteItem.word("test", .distantPast).is_expired())
|
||||
XCTAssertFalse(MuteItem.word("test", .distantFuture).is_expired())
|
||||
}
|
||||
func test_thread_is_expired() throws {
|
||||
XCTAssertTrue(MuteItem.thread(test_note.id, Date(timeIntervalSince1970: 0)).is_expired())
|
||||
XCTAssertTrue(MuteItem.thread(test_note.id, .distantPast).is_expired())
|
||||
XCTAssertFalse(MuteItem.thread(test_note.id, .distantFuture).is_expired())
|
||||
}
|
||||
|
||||
|
||||
// MARK: - `tag`
|
||||
func test_hashtag_tag() throws {
|
||||
XCTAssertEqual(MuteItem.hashtag(Hashtag(hashtag: "test"), nil).tag, ["t", "test"])
|
||||
XCTAssertEqual(MuteItem.hashtag(Hashtag(hashtag: "test"), Date(timeIntervalSince1970: 1704067200)).tag, ["t", "test", "1704067200"])
|
||||
}
|
||||
func test_user_tag() throws {
|
||||
XCTAssertEqual(MuteItem.user(test_pubkey, Date(timeIntervalSince1970: 1704067200)).tag, ["p", test_pubkey.hex(), "1704067200"])
|
||||
}
|
||||
func test_word_tag() throws {
|
||||
XCTAssertEqual(MuteItem.word("test", Date(timeIntervalSince1970: 1704067200)).tag, ["word", "test", "1704067200"])
|
||||
}
|
||||
func test_thread_tag() throws {
|
||||
XCTAssertEqual(MuteItem.thread(test_note.id, Date(timeIntervalSince1970: 1704067200)).tag, ["e", test_note.id.hex(), "1704067200"])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user