diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 7de66a5bd6..2798a29f71 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -88,6 +88,7 @@ library Simplex.Chat.Migrations.M20230317_hidden_profiles Simplex.Chat.Migrations.M20230318_file_description Simplex.Chat.Migrations.M20230321_agent_file_deleted + Simplex.Chat.Migrations.M20230328_files_protocol Simplex.Chat.Mobile Simplex.Chat.Mobile.WebRTC Simplex.Chat.Options diff --git a/src/Simplex/Chat/Migrations/M20230328_files_protocol.hs b/src/Simplex/Chat/Migrations/M20230328_files_protocol.hs new file mode 100644 index 0000000000..5690378301 --- /dev/null +++ b/src/Simplex/Chat/Migrations/M20230328_files_protocol.hs @@ -0,0 +1,18 @@ +{-# LANGUAGE QuasiQuotes #-} + +module Simplex.Chat.Migrations.M20230328_files_protocol where + +import Database.SQLite.Simple (Query) +import Database.SQLite.Simple.QQ (sql) + +m20230328_files_protocol :: Query +m20230328_files_protocol = + [sql| +ALTER TABLE files ADD COLUMN protocol TEXT NOT NULL DEFAULT 'smp'; +|] + +down_m20230328_files_protocol :: Query +down_m20230328_files_protocol = + [sql| +ALTER TABLE files DROP COLUMN protocol; +|] diff --git a/src/Simplex/Chat/Migrations/chat_schema.sql b/src/Simplex/Chat/Migrations/chat_schema.sql index ed1b303545..4fc96eb5dc 100644 --- a/src/Simplex/Chat/Migrations/chat_schema.sql +++ b/src/Simplex/Chat/Migrations/chat_schema.sql @@ -200,7 +200,8 @@ CREATE TABLE files( file_inline TEXT, agent_snd_file_id BLOB NULL, private_snd_file_descr TEXT NULL, - agent_snd_file_deleted INTEGER DEFAULT 0 CHECK(agent_snd_file_deleted NOT NULL) + agent_snd_file_deleted INTEGER DEFAULT 0 CHECK(agent_snd_file_deleted NOT NULL), + protocol TEXT NOT NULL DEFAULT 'smp' ); CREATE TABLE snd_files( file_id INTEGER NOT NULL REFERENCES files ON DELETE CASCADE, diff --git a/src/Simplex/Chat/Store.hs b/src/Simplex/Chat/Store.hs index 1d45e2fe92..becdcbb45f 100644 --- a/src/Simplex/Chat/Store.hs +++ b/src/Simplex/Chat/Store.hs @@ -363,6 +363,7 @@ import Simplex.Chat.Migrations.M20230303_group_link_role import Simplex.Chat.Migrations.M20230317_hidden_profiles import Simplex.Chat.Migrations.M20230318_file_description import Simplex.Chat.Migrations.M20230321_agent_file_deleted +import Simplex.Chat.Migrations.M20230328_files_protocol import Simplex.Chat.Protocol import Simplex.Chat.Types import Simplex.Chat.Util (week) @@ -432,7 +433,8 @@ schemaMigrations = ("20230303_group_link_role", m20230303_group_link_role, Nothing), ("20230317_hidden_profiles", m20230317_hidden_profiles, Just down_m20230317_hidden_profiles), ("20230318_file_description", m20230318_file_description, Just down_m20230318_file_description), - ("20230321_agent_file_deleted", m20230321_agent_file_deleted, Just down_m20230321_agent_file_deleted) + ("20230321_agent_file_deleted", m20230321_agent_file_deleted, Just down_m20230321_agent_file_deleted), + ("20230328_files_protocol", m20230328_files_protocol, Just down_m20230328_files_protocol) ] -- | The list of migrations in ascending order by date diff --git a/tests/ChatTests/Files.hs b/tests/ChatTests/Files.hs index 2f2d937444..9d631838d8 100644 --- a/tests/ChatTests/Files.hs +++ b/tests/ChatTests/Files.hs @@ -50,6 +50,7 @@ chatFileTests = do xit "send and receive file to group, fully asynchronous" testAsyncGroupFileTransfer describe "file transfer over XFTP" $ do it "send and receive file" testXFTPFileTransfer + it "send and receive file in group" testXFTPGroupFileTransfer it "with changed XFTP config: send and receive file" testXFTPWithChangedConfig it "with relative paths: send and receive file" testXFTPWithRelativePaths it "continue receiving file after restart" testXFTPContinueRcv @@ -943,6 +944,47 @@ testXFTPFileTransfer = where cfg = testCfg {xftpFileConfig = Just $ XFTPFileConfig {minFileSize = 0}, tempDir = Just "./tests/tmp"} +testXFTPGroupFileTransfer :: HasCallStack => FilePath -> IO () +testXFTPGroupFileTransfer = + testChatCfg3 cfg aliceProfile bobProfile cathProfile $ \alice bob cath -> do + withXFTPServer $ do + createGroup3 "team" alice bob cath + + alice #> "/f #team ./tests/fixtures/test.pdf" + alice <## "use /fc 1 to cancel sending" + concurrentlyN_ + [ do + bob <# "#team alice> sends file test.pdf (266.0 KiB / 272376 bytes)" + bob <## "use /fr 1 [/ | ] to receive it", + do + cath <# "#team alice> sends file test.pdf (266.0 KiB / 272376 bytes)" + cath <## "use /fr 1 [/ | ] to receive it" + ] + -- alice <## "started sending file 1 (test.pdf) to bob" -- TODO "started uploading" ? + -- alice <## "completed sending file 1 (test.pdf) to bob" -- TODO "completed uploading" ? + + bob ##> "/fr 1 ./tests/tmp" + bob + <### [ "saving file 1 from alice to ./tests/tmp/test.pdf", + "started receiving file 1 (test.pdf) from alice" + ] + bob <## "completed receiving file 1 (test.pdf) from alice" + + cath ##> "/fr 1 ./tests/tmp" + cath + <### [ "saving file 1 from alice to ./tests/tmp/test_1.pdf", + "started receiving file 1 (test.pdf) from alice" + ] + cath <## "completed receiving file 1 (test.pdf) from alice" + + src <- B.readFile "./tests/fixtures/test.pdf" + dest1 <- B.readFile "./tests/tmp/test.pdf" + dest2 <- B.readFile "./tests/tmp/test_1.pdf" + dest1 `shouldBe` src + dest2 `shouldBe` src + where + cfg = testCfg {xftpFileConfig = Just $ XFTPFileConfig {minFileSize = 0}, tempDir = Just "./tests/tmp"} + testXFTPWithChangedConfig :: HasCallStack => FilePath -> IO () testXFTPWithChangedConfig = testChatCfg2 cfg aliceProfile bobProfile $ \alice bob -> do