diff --git a/flutter b/flutter index 4d9e56e..9944297 160000 --- a/flutter +++ b/flutter @@ -1 +1 @@ -Subproject commit 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf +Subproject commit 9944297138845a94256f1cf37beb88ff9a8e811a diff --git a/lib/main.dart b/lib/main.dart index f20fbd5..3eca615 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -121,6 +121,7 @@ void main() async { }); final apiFactory = PaperlessApiFactoryImpl(sessionManager); + runApp( MultiProvider( providers: [ diff --git a/lib/main_dev.dart b/lib/main_dev.dart new file mode 100644 index 0000000..5fb095a --- /dev/null +++ b/lib/main_dev.dart @@ -0,0 +1,10 @@ + + +import 'package:mock_server/mock_server.dart'; +import 'package:paperless_mobile/main.dart' as ParentMain; + +void main() async { + await LocalMockApiServer().start(); + ParentMain.main(); +} + diff --git a/packages/mock_server/.gitignore b/packages/mock_server/.gitignore new file mode 100644 index 0000000..96486fd --- /dev/null +++ b/packages/mock_server/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/packages/mock_server/.metadata b/packages/mock_server/.metadata new file mode 100644 index 0000000..40e012c --- /dev/null +++ b/packages/mock_server/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + channel: stable + +project_type: package diff --git a/packages/mock_server/CHANGELOG.md b/packages/mock_server/CHANGELOG.md new file mode 100644 index 0000000..41cc7d8 --- /dev/null +++ b/packages/mock_server/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/mock_server/LICENSE b/packages/mock_server/LICENSE new file mode 100644 index 0000000..ba75c69 --- /dev/null +++ b/packages/mock_server/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/mock_server/README.md b/packages/mock_server/README.md new file mode 100644 index 0000000..02fe8ec --- /dev/null +++ b/packages/mock_server/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/mock_server/analysis_options.yaml b/packages/mock_server/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/packages/mock_server/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/mock_server/fixtures/correspondents.json b/packages/mock_server/fixtures/correspondents.json new file mode 100644 index 0000000..d43ff66 --- /dev/null +++ b/packages/mock_server/fixtures/correspondents.json @@ -0,0 +1,257 @@ +{ + "count": 27, + "next": "http://localhost:8000/api/correspondents/?page=2", + "previous": null, + "results": [ + { + "id": 9, + "slug": "abc-test-correspondent", + "name": "ABC Test Correspondent", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 13, + "slug": "corresp-10", + "name": "Corresp 10", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 14, + "slug": "corresp-11", + "name": "Corresp 11", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 15, + "slug": "corresp-12", + "name": "Corresp 12", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 16, + "slug": "corresp-13", + "name": "Corresp 13", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 18, + "slug": "corresp-15", + "name": "Corresp 15", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 19, + "slug": "corresp-16", + "name": "Corresp 16", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 20, + "slug": "corresp-17", + "name": "Corresp 17", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 21, + "slug": "corresp-18", + "name": "Corresp 18", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 22, + "slug": "corresp-19", + "name": "Corresp 19", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 23, + "slug": "corresp-20", + "name": "Corresp 20", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 24, + "slug": "corresp-21", + "name": "Corresp 21", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 25, + "slug": "corresp-22", + "name": "Corresp 22", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 26, + "slug": "corresp-23", + "name": "Corresp 23", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 5, + "slug": "corresp-3", + "name": "Corresp 3", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 6, + "slug": "corresp-4", + "name": "Corresp 4", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 7, + "slug": "corresp-5", + "name": "Corresp 5", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 8, + "slug": "corresp-6", + "name": "Corresp 6", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 10, + "slug": "corresp-7", + "name": "Corresp 7", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 11, + "slug": "corresp-8", + "name": "Corresp 8", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 12, + "slug": "corresp-9", + "name": "Corresp 9", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 17, + "slug": "correspondent-14", + "name": "Correspondent 14", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 0, + "last_correspondence": null + }, + { + "id": 2, + "slug": "correspondent-2", + "name": "Correspondent 2", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 7, + "last_correspondence": "2021-01-20T23:37:58.204614Z" + }, + { + "id": 27, + "slug": "correspondent-slug", + "name": "Correspondent Slug", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 1, + "last_correspondence": "2022-03-16T03:48:50.089624Z" + }, + { + "id": 4, + "slug": "newest-correspondent", + "name": "Newest Correspondent", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 1, + "last_correspondence": "2021-02-07T08:00:00Z" + } + ] +} diff --git a/packages/mock_server/fixtures/doc_types.json b/packages/mock_server/fixtures/doc_types.json new file mode 100644 index 0000000..eb2d74a --- /dev/null +++ b/packages/mock_server/fixtures/doc_types.json @@ -0,0 +1,25 @@ +{ + "count": 2, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "slug": "test", + "name": "Test Doc Type", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 1 + }, + { + "id": 2, + "slug": "test2", + "name": "Test Doc Type 2", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "document_count": 1 + } + ] +} diff --git a/packages/mock_server/fixtures/documents.json b/packages/mock_server/fixtures/documents.json new file mode 100644 index 0000000..87bc3a4 --- /dev/null +++ b/packages/mock_server/fixtures/documents.json @@ -0,0 +1,197 @@ +{ + "count": 3, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "correspondent": 9, + "document_type": 1, + "storage_path": null, + "title": "No latin title", + "content": "Test document PDF \n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla est purus, ultrices in porttitor \nin, accumsan non quam. Nam consectetur porttitor rhoncus. Curabitur eu est et leo feugiat \nauctor vel quis lorem. Ut et ligula dolor, sit amet consequat lorem. Aliquam porta eros sed \nvelit imperdiet egestas. Maecenas tempus eros ut diam ullamcorper id dictum libero \ntempor. Donec quis augue quis magna condimentum lobortis. Quisque imperdiet ipsum vel \nmagna viverra rutrum. Cras viverra molestie urna, vitae vestibulum turpis varius id. \nVestibulum mollis, arcu iaculis bibendum varius, velit sapien blandit metus, ac posuere lorem \nnulla ac dolor. Maecenas urna elit, tincidunt in dapibus nec, vehicula eu dui. Duis lacinia \nfringilla massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur \nridiculus mus. Ut consequat ultricies est, non rhoncus mauris congue porta. Vivamus viverra \nsuscipit felis eget condimentum. Cum sociis natoque penatibus et magnis dis parturient \nmontes, nascetur ridiculus mus. Integer bibendum sagittis ligula, non faucibus nulla volutpat \nvitae. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. \nIn aliquet quam et velit bibendum accumsan. Cum sociis natoque penatibus et magnis dis \nparturient montes, nascetur ridiculus mus. Vestibulum vitae ipsum nec arcu semper \nadipiscing at ac lacus. Praesent id pellentesque orci. Morbi congue viverra nisl nec rhoncus. \nInteger mattis, ipsum a tincidunt commodo, lacus arcu elementum elit, at mollis eros ante ac \nrisus. In volutpat, ante at pretium ultricies, velit magna suscipit enim, aliquet blandit massa \norci nec lorem. Nulla facilisi. Duis eu vehicula arcu. Nulla facilisi. Maecenas pellentesque \nvolutpat felis, quis tristique ligula luctus vel. Sed nec mi eros. Integer augue enim, sollicitudin \nullamcorper mattis eget, aliquam in est. Morbi sollicitudin libero nec augue dignissim ut \nconsectetur dui volutpat. Nulla facilisi. Mauris egestas vestibulum neque cursus tincidunt. \nDonec sit amet pulvinar orci. \nQuisque volutpat pharetra tincidunt. Fusce sapien arcu, molestie eget varius egestas, \nfaucibus ac urna. Sed at nisi in velit egestas aliquam ut a felis. Aenean malesuada iaculis nisl, \nut tempor lacus egestas consequat. Nam nibh lectus, gravida sed egestas ut, feugiat quis \ndolor. Donec eu leo enim, non laoreet ante. Morbi dictum tempor vulputate. Phasellus \nultricies risus vel augue sagittis euismod. Vivamus tincidunt placerat nisi in aliquam. Cras \nquis mi ac nunc pretium aliquam. Aenean elementum erat ac metus commodo rhoncus. \nAliquam nulla augue, porta non sagittis quis, accumsan vitae sem. Phasellus id lectus tortor, \neget pulvinar augue. Etiam eget velit ac purus fringilla blandit. Donec odio odio, sagittis sed \niaculis sed, consectetur eget sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. \nMaecenas accumsan velit vel turpis rutrum in sodales diam placerat. \nQuisque luctus ullamcorper velit sit amet lobortis. Etiam ligula felis, vulputate quis rhoncus \nnec, fermentum eget odio. Vivamus vel ipsum ac augue sodales mollis euismod nec tellus. \nFusce et augue rutrum nunc semper vehicula vel semper nisl. Nam laoreet euismod quam at \nvarius. Sed aliquet auctor nibh. Curabitur malesuada fermentum lacus vel accumsan. Duis \nornare scelerisque nulla, ac pulvinar ligula tempus sit amet. In placerat nulla ac ante \nscelerisque posuere. Phasellus at ante felis. Sed hendrerit risus a metus posuere rutrum. \nPhasellus eu augue dui. Proin in vestibulum ipsum. Aenean accumsan mollis sapien, ut \neleifend sem blandit at. Vivamus luctus mi eget lorem lobortis pharetra. Phasellus at tortor \nquam, a volutpat purus. Etiam sollicitudin arcu vel elit bibendum et imperdiet risus tincidunt. \nEtiam elit velit, posuere ut pulvinar ac, condimentum eget justo. Fusce a erat velit. Vivamus \nimperdiet ultrices orci in hendrerit.", + "tags": [ + 4 + ], + "created": "2022-03-22T07:24:18Z", + "created_date": "2022-03-22", + "modified": "2022-03-22T07:24:23.264859Z", + "added": "2022-03-22T07:24:22.922631Z", + "archive_serial_number": null, + "original_file_name": "2022-03-22 no latin title.pdf", + "archived_file_name": "2022-03-22 no latin title.pdf", + "owner": null, + "user_can_change": true, + "permissions": { + "view": { + "users": [], + "groups": [] + }, + "change": { + "users": [], + "groups": [] + } + }, + "notes": [ + { + "id": 9, + "note": "Testing one more time", + "created": "2022-02-18T04:24:55.176008Z", + "user": 15 + }, + { + "id": 8, + "note": "Another note", + "created": "2021-11-08T04:24:47.925042Z", + "user": 3 + }, + { + "id": 7, + "note": "Cupcake ipsum dolor sit amet cheesecake candy cookie tiramisu. Donut chocolate chupa chups macaroon brownie halvah pie cheesecake gummies. Sweet chocolate bar candy donut gummi bears bear claw liquorice bonbon shortbread.\n\nDonut chocolate bar candy wafer wafer tiramisu. Gummies chocolate cake muffin toffee carrot cake macaroon. Toffee toffee jelly beans danish lollipop cake.", + "created": "2021-02-08T02:37:49.724132Z", + "user": 3 + } + ] + }, + { + "id": 2, + "correspondent": null, + "document_type": null, + "storage_path": 2, + "title": "lorem ipsum dolor sit amet", + "content": "Test document PDF", + "tags": [], + "created": "2022-03-23T07:24:18Z", + "created_date": "2022-03-23", + "modified": "2022-03-23T07:24:23.264859Z", + "added": "2022-03-23T07:24:22.922631Z", + "archive_serial_number": 12345, + "original_file_name": "2022-03-23 lorem ipsum dolor sit amet.pdf", + "archived_file_name": "2022-03-23 llorem ipsum dolor sit amet.pdf", + "owner": null, + "user_can_change": true, + "permissions": { + "view": { + "users": [], + "groups": [] + }, + "change": { + "users": [], + "groups": [] + } + }, + "notes": [] + }, + { + "id": 3, + "correspondent": 14, + "document_type": 1, + "storage_path": null, + "title": "dolor", + "content": "Test document PDF", + "tags": [ + 2 + ], + "created": "2022-03-24T07:24:18Z", + "created_date": "2022-03-24", + "modified": "2022-03-24T07:24:23.264859Z", + "added": "2022-03-24T07:24:22.922631Z", + "archive_serial_number": null, + "original_file_name": "2022-03-24 dolor.pdf", + "archived_file_name": "2022-03-24 dolor.pdf", + "owner": null, + "user_can_change": true, + "permissions": { + "view": { + "users": [], + "groups": [] + }, + "change": { + "users": [], + "groups": [] + } + }, + "notes": [] + }, + { + "id": 4, + "correspondent": 9, + "document_type": 2, + "storage_path": null, + "title": "sit amet", + "content": "Test document PDF", + "tags": [ + 4, 5 + ], + "created": "2022-06-01T07:24:18Z", + "created_date": "2022-06-01", + "modified": "2022-06-01T07:24:23.264859Z", + "added": "2022-06-01T07:24:22.922631Z", + "archive_serial_number": 12347, + "original_file_name": "2022-06-01 sit amet.pdf", + "archived_file_name": "2022-06-01 sit amet.pdf", + "owner": null, + "user_can_change": true, + "permissions": { + "view": { + "users": [], + "groups": [] + }, + "change": { + "users": [], + "groups": [] + } + }, + "notes": [] + }, + { + "id": 5, + "correspondent": null, + "document_type": null, + "storage_path": null, + "title": "Doc 5", + "content": "Test document 5", + "tags": [], + "created": "2023-05-01T07:24:18Z", + "created_date": "2023-05-02", + "modified": "2023-05-02T07:24:23.264859Z", + "added": "2023-05-02T07:24:22.922631Z", + "archive_serial_number": null, + "original_file_name": "doc5.pdf", + "archived_file_name": "doc5.pdf", + "owner": 15, + "user_can_change": true, + "permissions": { + "view": { + "users": [], + "groups": [] + }, + "change": { + "users": [], + "groups": [] + } + }, + "notes": [] + }, + { + "id": 6, + "correspondent": null, + "document_type": null, + "storage_path": null, + "title": "Doc 6", + "content": "Test document 6", + "tags": [], + "created": "2023-05-01T10:24:18Z", + "created_date": "2023-05-02", + "modified": "2023-05-02T10:24:23.264859Z", + "added": "2023-05-02T10:24:22.922631Z", + "archive_serial_number": null, + "original_file_name": "doc6.pdf", + "archived_file_name": "doc6.pdf", + "owner": 6, + "user_can_change": true, + + "notes": [] + } + ] +} diff --git a/packages/mock_server/fixtures/groups.json b/packages/mock_server/fixtures/groups.json new file mode 100644 index 0000000..f6051be --- /dev/null +++ b/packages/mock_server/fixtures/groups.json @@ -0,0 +1,119 @@ +{ + "count": 2, + "next": null, + "previous": null, + "results": [ + { + "id": 6, + "name": "Another Group", + "permissions": [ + "add_user", + "change_user", + "delete_user", + "view_user", + "add_note", + "change_note", + "delete_note", + "view_note" + ] + }, + { + "id": 1, + "name": "First Group", + "permissions": [ + "add_group", + "change_group", + "delete_group", + "view_group", + "add_permission", + "change_permission", + "delete_permission", + "view_permission", + "add_token", + "change_token", + "delete_token", + "view_token", + "add_tokenproxy", + "change_tokenproxy", + "delete_tokenproxy", + "view_tokenproxy", + "add_contenttype", + "change_contenttype", + "delete_contenttype", + "view_contenttype", + "add_chordcounter", + "change_chordcounter", + "delete_chordcounter", + "view_chordcounter", + "add_groupresult", + "change_groupresult", + "delete_groupresult", + "view_groupresult", + "add_taskresult", + "change_taskresult", + "delete_taskresult", + "view_taskresult", + "add_failure", + "change_failure", + "delete_failure", + "view_failure", + "add_ormq", + "change_ormq", + "delete_ormq", + "view_ormq", + "add_schedule", + "change_schedule", + "delete_schedule", + "view_schedule", + "add_success", + "change_success", + "delete_success", + "view_success", + "add_task", + "change_task", + "delete_task", + "view_task", + "add_note", + "change_note", + "delete_note", + "view_note", + "add_correspondent", + "change_correspondent", + "delete_correspondent", + "view_correspondent", + "add_document", + "change_document", + "delete_document", + "view_document", + "add_documenttype", + "change_documenttype", + "delete_documenttype", + "view_documenttype", + "add_frontendsettings", + "change_frontendsettings", + "delete_frontendsettings", + "view_frontendsettings", + "add_log", + "change_log", + "delete_log", + "view_log", + "add_savedview", + "change_savedview", + "delete_savedview", + "view_savedview", + "add_savedviewfilterrule", + "change_savedviewfilterrule", + "delete_savedviewfilterrule", + "view_savedviewfilterrule", + "add_taskattributes", + "change_taskattributes", + "delete_taskattributes", + "view_taskattributes", + "add_session", + "change_session", + "delete_session", + "view_session" + ] + } + ] +} diff --git a/packages/mock_server/fixtures/lorem-ipsum.png b/packages/mock_server/fixtures/lorem-ipsum.png new file mode 100644 index 0000000..a74f2ae Binary files /dev/null and b/packages/mock_server/fixtures/lorem-ipsum.png differ diff --git a/packages/mock_server/fixtures/metadata.json b/packages/mock_server/fixtures/metadata.json new file mode 100644 index 0000000..f5bfd95 --- /dev/null +++ b/packages/mock_server/fixtures/metadata.json @@ -0,0 +1 @@ +{"original_checksum":"e959bc7d593245d92685213264e962ba","original_size":963754,"original_mime_type":"application/pdf","media_filename":"2022/lorem-ipsum.pdf","has_archive_version":true,"original_metadata":[],"archive_checksum":"5a1f46a9150bcade978c764b039ce4d0","archive_media_filename":"2022/lorem-ipsum.pdf","archive_size":351160,"archive_metadata":[{"namespace":"http://ns.adobe.com/pdf/1.3/","prefix":"pdf","key":"Producer","value":"pikepdf5.0.1"},{"namespace":"http://ns.adobe.com/xap/1.0/","prefix":"xmp","key":"ModifyDate","value":"2022-03-22T04:53:18+00:00"},{"namespace":"http://ns.adobe.com/xap/1.0/","prefix":"xmp","key":"CreateDate","value":"2022-03-22T18:05:43+00:00"},{"namespace":"http://ns.adobe.com/xap/1.0/","prefix":"xmp","key":"CreatorTool","value":"ocrmypdf13.4.0/TesseractOCR-PDF4.1.1"},{"namespace":"http://ns.adobe.com/xap/1.0/mm/","prefix":"xmpMM","key":"DocumentID","value":"uuid:df27edcf-e34a-11f7-0000-8fa6067a3c04"},{"namespace":"http://purl.org/dc/elements/1.1/","prefix":"dc","key":"format","value":"application/pdf"},{"namespace":"http://purl.org/dc/elements/1.1/","prefix":"dc","key":"title","value":"ScannedDocument"},{"namespace":"http://www.aiim.org/pdfa/ns/id/","prefix":"pdfaid","key":"part","value":"2"},{"namespace":"http://www.aiim.org/pdfa/ns/id/","prefix":"pdfaid","key":"conformance","value":"B"},{"namespace":"http://purl.org/dc/elements/1.1/","prefix":"dc","key":"creator","value":"None"},{"namespace":"http://ns.adobe.com/xap/1.0/","prefix":"xmp","key":"MetadataDate","value":"2022-03-22T21:53:18.882551-07:00"}]} diff --git a/packages/mock_server/fixtures/notes.json b/packages/mock_server/fixtures/notes.json new file mode 100644 index 0000000..dfd4449 --- /dev/null +++ b/packages/mock_server/fixtures/notes.json @@ -0,0 +1,26 @@ +[ + { + "id": 10, + "note": "Testing new note", + "created": "2022-08-08T04:24:55.176008Z", + "user": 3 + }, + { + "id": 9, + "note": "Testing one more time", + "created": "2022-02-18T04:24:55.176008Z", + "user": 15 + }, + { + "id": 8, + "note": "Another note", + "created": "2021-11-08T04:24:47.925042Z", + "user": 3 + }, + { + "id": 7, + "note": "Cupcake ipsum dolor sit amet cheesecake candy cookie tiramisu. Donut chocolate chupa chups macaroon brownie halvah pie cheesecake gummies. Sweet chocolate bar candy donut gummi bears bear claw liquorice bonbon shortbread.\n\nDonut chocolate bar candy wafer wafer tiramisu. Gummies chocolate cake muffin toffee carrot cake macaroon. Toffee toffee jelly beans danish lollipop cake.", + "created": "2021-02-08T02:37:49.724132Z", + "user": 3 + } +] \ No newline at end of file diff --git a/packages/mock_server/fixtures/saved_views.json b/packages/mock_server/fixtures/saved_views.json new file mode 100644 index 0000000..64afcf3 --- /dev/null +++ b/packages/mock_server/fixtures/saved_views.json @@ -0,0 +1,44 @@ +{ + "count": 3, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "name": "Inbox", + "show_on_dashboard": true, + "show_in_sidebar": true, + "sort_field": "created", + "sort_reverse": true, + "filter_rules": [ + { + "rule_type": 6, + "value": "18" + } + ] + }, + { + "id": 2, + "name": "Recently Added", + "show_on_dashboard": true, + "show_in_sidebar": false, + "sort_field": "created", + "sort_reverse": true, + "filter_rules": [] + }, + { + "id": 11, + "name": "Taxes", + "show_on_dashboard": false, + "show_in_sidebar": true, + "sort_field": "created", + "sort_reverse": true, + "filter_rules": [ + { + "rule_type": 6, + "value": "39" + } + ] + } + ] +} diff --git a/packages/mock_server/fixtures/statistics.json b/packages/mock_server/fixtures/statistics.json new file mode 100644 index 0000000..0cfe52b --- /dev/null +++ b/packages/mock_server/fixtures/statistics.json @@ -0,0 +1,16 @@ +{ + "documents_total": 64, + "documents_inbox": null, + "inbox_tag": null, + "document_file_type_counts": [ + { + "mime_type": "application/pdf", + "mime_type_count": 35 + }, + { + "mime_type": "image/jpeg", + "mime_type_count": 29 + } + ], + "character_count": 309035 +} \ No newline at end of file diff --git a/packages/mock_server/fixtures/storage_paths.json b/packages/mock_server/fixtures/storage_paths.json new file mode 100644 index 0000000..86ae9b7 --- /dev/null +++ b/packages/mock_server/fixtures/storage_paths.json @@ -0,0 +1,17 @@ +{ + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 2, + "slug": "year-title", + "name": "Year - Title", + "path": "{created_year}/{title}", + "match": "", + "matching_algorithm": 6, + "is_insensitive": true, + "document_count": 1 + } + ] +} diff --git a/packages/mock_server/fixtures/suggestions.json b/packages/mock_server/fixtures/suggestions.json new file mode 100644 index 0000000..39b9595 --- /dev/null +++ b/packages/mock_server/fixtures/suggestions.json @@ -0,0 +1 @@ +{"correspondents":[],"tags":[3],"document_types":[1]} \ No newline at end of file diff --git a/packages/mock_server/fixtures/tags.json b/packages/mock_server/fixtures/tags.json new file mode 100644 index 0000000..eefee90 --- /dev/null +++ b/packages/mock_server/fixtures/tags.json @@ -0,0 +1,103 @@ +{ + "count": 8, + "next": null, + "previous": null, + "results": [ + { + "id": 4, + "slug": "another-sample-tag", + "name": "Another Sample Tag", + "color": "#a6cee3", + "text_color": "#000000", + "match": "", + "matching_algorithm": 6, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 3 + }, + { + "id": 7, + "slug": "newone", + "name": "NewOne", + "color": "#9e4ad1", + "text_color": "#ffffff", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 2 + }, + { + "id": 6, + "slug": "partial-tag", + "name": "Partial Tag", + "color": "#72dba7", + "text_color": "#000000", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 1 + }, + { + "id": 2, + "slug": "tag-2", + "name": "Tag 2", + "color": "#612db7", + "text_color": "#ffffff", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 3 + }, + { + "id": 3, + "slug": "tag-3", + "name": "Tag 3", + "color": "#b2df8a", + "text_color": "#000000", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 4 + }, + { + "id": 5, + "slug": "tagwithpartial", + "name": "TagWithPartial", + "color": "#3b2db4", + "text_color": "#ffffff", + "match": "", + "matching_algorithm": 6, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 2 + }, + { + "id": 8, + "slug": "test-another", + "name": "Test Another", + "color": "#3ccea5", + "text_color": "#000000", + "match": "", + "matching_algorithm": 4, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 0 + }, + { + "id": 1, + "slug": "test-tag", + "name": "Test Tag", + "color": "#fb9a99", + "text_color": "#000000", + "match": "", + "matching_algorithm": 1, + "is_insensitive": true, + "is_inbox_tag": false, + "document_count": 4 + } + ] +} diff --git a/packages/mock_server/fixtures/tasks.json b/packages/mock_server/fixtures/tasks.json new file mode 100644 index 0000000..25e4d07 --- /dev/null +++ b/packages/mock_server/fixtures/tasks.json @@ -0,0 +1,142 @@ +[ + { + "id": 141, + "type": "file", + "result": "sample 2.pdf: Not consuming sample 2.pdf: It is a duplicate. : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ngx.nosync-udqDZzaE/lib/python3.8/site-packages/django_q/cluster.py\", line 432, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/paperless-ngx/src/documents/tasks.py\", line 316, in consume_file\n document = Consumer().try_consume_file(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 218, in try_consume_file\n self.pre_check_duplicate()\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 113, in pre_check_duplicate\n self._fail(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 84, in _fail\n raise ConsumerError(f\"{self.filename}: {log_message or message}\")\ndocuments.consumer.ConsumerError: sample 2.pdf: Not consuming sample 2.pdf: It is a duplicate.\n", + "status": "FAILURE", + "task_id": "d8ddbe298a42427d82553206ddf0bc94", + "task_file_name": "sample 2.pdf", + "date_created": "2022-05-26T23:17:38.333474-07:00", + "date_done": null, + "acknowledged": false, + "related_document": null + }, + { + "id": 132, + "type": "file", + "result": " : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 131, in get_version\n env=env,\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 68, in run\n proc = subprocess_run(args, env=env, **kwargs)\n File \"/Users/admin/opt/anaconda3/envs/paperless-ng/lib/python3.6/subprocess.py\", line 423, in run\n with Popen(*popenargs, **kwargs) as process:\n File \"/Users/admin/opt/anaconda3/envs/paperless-ng/lib/python3.6/subprocess.py\", line 729, in __init__\n restore_signals, start_new_session)\n File \"/Users/admin/opt/anaconda3/envs/paperless-ng/lib/python3.6/subprocess.py\", line 1364, in _execute_child\n raise child_exception_type(errno_num, err_msg, err_filename)\nFileNotFoundError: [Errno 2] No such file or directory: 'unpaper': 'unpaper'\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 287, in check_external_program\n found_version = version_checker()\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_exec/unpaper.py\", line 34, in version\n return get_version('unpaper')\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 137, in get_version\n ) from e\nocrmypdf.exceptions.MissingDependencyError: Could not find program 'unpaper' on the PATH\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/paperless_tesseract/parsers.py\", line 176, in parse\n ocrmypdf.ocr(**ocr_args)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/api.py\", line 315, in ocr\n check_options(options, plugin_manager)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_validation.py\", line 260, in check_options\n _check_options(options, plugin_manager, ocr_engine_languages)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_validation.py\", line 250, in _check_options\n check_options_preprocessing(options)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/_validation.py\", line 128, in check_options_preprocessing\n required_for=['--clean, --clean-final'],\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/ocrmypdf/subprocess.py\", line 293, in check_external_program\n raise MissingDependencyError()\nocrmypdf.exceptions.MissingDependencyError\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 179, in try_consume_file\n document_parser.parse(self.path, mime_type, self.filename)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/paperless_tesseract/parsers.py\", line 197, in parse\n raise ParseError(e)\ndocuments.parsers.ParseError\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/django_q/cluster.py\", line 436, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/tasks.py\", line 73, in consume_file\n override_tag_ids=override_tag_ids)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 196, in try_consume_file\n raise ConsumerError(e)\ndocuments.consumer.ConsumerError\n", + "status": "FAILURE", + "task_id": "4c554075552c4cc985abd76e6f274c90", + "task_file_name": "pdf-sample 10.24.48 PM.pdf", + "date_created": "2022-05-26T14:26:07.846365-07:00", + "date_done": null, + "acknowledged": null + }, + { + "id": 115, + "type": "file", + "result": "2021-01-24 2021-01-20 sample_wide_orange.pdf: Document is a duplicate : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/django_q/cluster.py\", line 436, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/tasks.py\", line 75, in consume_file\n task_id=task_id\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 168, in try_consume_file\n self.pre_check_duplicate()\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 85, in pre_check_duplicate\n self._fail(\"Document is a duplicate\")\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 53, in _fail\n raise ConsumerError(f\"{self.filename}: {message}\")\ndocuments.consumer.ConsumerError: 2021-01-24 2021-01-20 sample_wide_orange.pdf: Document is a duplicate\n", + "status": "FAILURE", + "task_id": "86494713646a4364b01da17aadca071d", + "task_file_name": "2021-01-24 2021-01-20 sample_wide_orange.pdf", + "date_created": "2022-05-26T14:26:07.817608-07:00", + "date_done": null, + "acknowledged": null + }, + { + "id": 85, + "type": "file", + "result": "cannot open resource : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/django_q/cluster.py\", line 436, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/tasks.py\", line 81, in consume_file\n task_id=task_id\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/consumer.py\", line 244, in try_consume_file\n self.path, mime_type, self.filename)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/documents/parsers.py\", line 302, in get_optimised_thumbnail\n thumbnail = self.get_thumbnail(document_path, mime_type, file_name)\n File \"/Users/admin/Documents/Work/Contributions/paperless-ng/src/paperless_text/parsers.py\", line 29, in get_thumbnail\n layout_engine=ImageFont.LAYOUT_BASIC)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/PIL/ImageFont.py\", line 852, in truetype\n return freetype(font)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/PIL/ImageFont.py\", line 849, in freetype\n return FreeTypeFont(font, size, index, encoding, layout_engine)\n File \"/Users/admin/.local/share/virtualenvs/paperless-ng/lib/python3.6/site-packages/PIL/ImageFont.py\", line 210, in __init__\n font, size, index, encoding, layout_engine=layout_engine\nOSError: cannot open resource\n", + "status": "FAILURE", + "task_id": "abca803fa46342e1ac81f3d3f2080e79", + "task_file_name": "simple.txt", + "date_created": "2022-05-26T14:26:07.771541-07:00", + "date_done": null, + "acknowledged": null + }, + { + "id": 41, + "type": "file", + "result": "commands.txt: Not consuming commands.txt: It is a duplicate. : Traceback (most recent call last):\n File \"/Users/admin/.local/share/virtualenvs/paperless-ngx.nosync-udqDZzaE/lib/python3.8/site-packages/django_q/cluster.py\", line 432, in worker\n res = f(*task[\"args\"], **task[\"kwargs\"])\n File \"/Users/admin/Documents/paperless-ngx/src/documents/tasks.py\", line 70, in consume_file\n document = Consumer().try_consume_file(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 199, in try_consume_file\n self.pre_check_duplicate()\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 97, in pre_check_duplicate\n self._fail(\n File \"/Users/admin/Documents/paperless-ngx/src/documents/consumer.py\", line 69, in _fail\n raise ConsumerError(f\"{self.filename}: {log_message or message}\")\ndocuments.consumer.ConsumerError: commands.txt: Not consuming commands.txt: It is a duplicate.\n", + "status": "FAILURE", + "task_id": "0af67672e8e14404b060d4cf8f69313d", + "task_file_name": "commands.txt", + "date_created": "2022-05-26T14:26:07.704247-07:00", + "date_done": null, + "acknowledged": null + }, + { + "id": 10, + "type": "file", + "result": "Success. New document id 260 created", + "status": "SUCCESS", + "task_id": "b7629a0f41bd40c7a3ea4680341321b5", + "task_file_name": "2022-03-24+Sonstige+ScanPC2022-03-24_081058.pdf", + "date_created": "2022-05-26T14:26:07.670577-07:00", + "date_done": "2022-05-26T14:26:07.670577-07:00", + "acknowledged": false, + "related_document": 260 + }, + { + "id": 9, + "type": "file", + "result": "Success. New document id 261 created", + "status": "SUCCESS", + "task_id": "02e276a86a424ccfb83309df5d8594be", + "task_file_name": "2sample-pdf-with-images.pdf", + "date_created": "2022-05-26T14:26:07.668987-07:00", + "date_done": "2022-05-26T14:26:07.668987-07:00", + "acknowledged": false, + "related_document": 261 + }, + { + "id": 8, + "type": "file", + "result": "Success. New document id 262 created", + "status": "SUCCESS", + "task_id": "41229b8be9b445c0a523697d0f58f13e", + "task_file_name": "2sample-pdf-with-images_pw.pdf", + "date_created": "2022-05-26T14:26:07.667993-07:00", + "date_done": "2022-05-26T14:26:07.667993-07:00", + "acknowledged": false, + "related_document": 262 + }, + { + "id": 6, + "type": "file", + "result": "Success. New document id 264 created", + "status": "SUCCESS", + "task_id": "bbbca32d408c4619bd0b512a8327c773", + "task_file_name": "homebridge.log", + "date_created": "2022-05-26T14:26:07.665560-07:00", + "date_done": "2022-05-26T14:26:07.665560-07:00", + "acknowledged": false, + "related_document": 264 + }, + { + "id": 5, + "type": "file", + "result": "Success. New document id 265 created", + "status": "SUCCESS", + "task_id": "00ab285ab4bf482ab30c7d580b252ecb", + "task_file_name": "IMG_7459.PNG", + "date_created": "2022-05-26T14:26:07.664506-07:00", + "date_done": "2022-05-26T14:26:07.664506-07:00", + "acknowledged": false, + "related_document": 265 + }, + { + "id": 3, + "type": "file", + "result": "Success. New document id 267 created", + "status": "SUCCESS", + "task_id": "289c5163cfec410db42948a0cacbeb9c", + "task_file_name": "IMG_7459.PNG", + "date_created": "2022-05-26T14:26:07.659661-07:00", + "date_done": "2022-05-26T14:26:07.659661-07:00", + "acknowledged": false, + "related_document": 267 + }, + { + "id": 1, + "type": "file", + "result": null, + "status": "STARTED", + "task_id": "7a4ebdb2bde04311935284027ef8ca65", + "task_file_name": "2019-08-04 DSA Questionnaire - 5-8-19.pdf", + "date_created": "2022-05-26T14:26:07.655276-07:00", + "date_done": null, + "acknowledged": false, + "related_document": null + } +] diff --git a/packages/mock_server/fixtures/ui_settings.json b/packages/mock_server/fixtures/ui_settings.json new file mode 100644 index 0000000..b885eec --- /dev/null +++ b/packages/mock_server/fixtures/ui_settings.json @@ -0,0 +1,163 @@ +{ + "user": { + "id": 1, + "username": "admin", + "is_superuser": true, + "groups": [] + }, + "settings": { + "language": "", + "bulk_edit": { + "confirmation_dialogs": true, + "apply_on_close": false + }, + "documentListSize": 50, + "dark_mode": { + "use_system": true, + "enabled": "false", + "thumb_inverted": "true" + }, + "theme": { + "color": "#b198e5" + }, + "document_details": { + "native_pdf_viewer": false + }, + "date_display": { + "date_locale": "", + "date_format": "mediumDate" + }, + "notifications": { + "consumer_new_documents": true, + "consumer_success": true, + "consumer_failed": true, + "consumer_suppress_on_dashboard": true + } + }, + "permissions": [ + "add_logentry", + "change_logentry", + "delete_logentry", + "view_logentry", + "add_group", + "change_group", + "delete_group", + "view_group", + "add_permission", + "change_permission", + "delete_permission", + "view_permission", + "add_user", + "change_user", + "delete_user", + "view_user", + "add_token", + "change_token", + "delete_token", + "view_token", + "add_tokenproxy", + "change_tokenproxy", + "delete_tokenproxy", + "view_tokenproxy", + "add_contenttype", + "change_contenttype", + "delete_contenttype", + "view_contenttype", + "add_chordcounter", + "change_chordcounter", + "delete_chordcounter", + "view_chordcounter", + "add_groupresult", + "change_groupresult", + "delete_groupresult", + "view_groupresult", + "add_taskresult", + "change_taskresult", + "delete_taskresult", + "view_taskresult", + "add_failure", + "change_failure", + "delete_failure", + "view_failure", + "add_ormq", + "change_ormq", + "delete_ormq", + "view_ormq", + "add_schedule", + "change_schedule", + "delete_schedule", + "view_schedule", + "add_success", + "change_success", + "delete_success", + "view_success", + "add_task", + "change_task", + "delete_task", + "view_task", + "add_note", + "change_note", + "delete_note", + "view_note", + "add_correspondent", + "change_correspondent", + "delete_correspondent", + "view_correspondent", + "add_document", + "change_document", + "delete_document", + "view_document", + "add_documenttype", + "change_documenttype", + "delete_documenttype", + "view_documenttype", + "add_frontendsettings", + "change_frontendsettings", + "delete_frontendsettings", + "view_frontendsettings", + "add_log", + "change_log", + "delete_log", + "view_log", + "add_paperlesstask", + "change_paperlesstask", + "delete_paperlesstask", + "view_paperlesstask", + "add_savedview", + "change_savedview", + "delete_savedview", + "view_savedview", + "add_savedviewfilterrule", + "change_savedviewfilterrule", + "delete_savedviewfilterrule", + "view_savedviewfilterrule", + "add_storagepath", + "change_storagepath", + "delete_storagepath", + "view_storagepath", + "add_tag", + "change_tag", + "delete_tag", + "view_tag", + "add_taskattributes", + "change_taskattributes", + "delete_taskattributes", + "view_taskattributes", + "add_uisettings", + "change_uisettings", + "delete_uisettings", + "view_uisettings", + "add_mailaccount", + "change_mailaccount", + "delete_mailaccount", + "view_mailaccount", + "add_mailrule", + "change_mailrule", + "delete_mailrule", + "view_mailrule", + "add_session", + "change_session", + "delete_session", + "view_session" + ] +} diff --git a/packages/mock_server/fixtures/user-1.json b/packages/mock_server/fixtures/user-1.json new file mode 100644 index 0000000..cc264b0 --- /dev/null +++ b/packages/mock_server/fixtures/user-1.json @@ -0,0 +1,148 @@ +{ + "id": 1, + "username": "admin", + "password": "**********", + "email": "test2@test.com", + "first_name": "", + "last_name": "", + "date_joined": "2022-02-14T23:11:09.103293Z", + "is_staff": true, + "is_active": true, + "is_superuser": true, + "groups": [], + "user_permissions": [], + "inherited_permissions": [ + "auth.delete_permission", + "paperless_mail.change_mailrule", + "django_celery_results.add_taskresult", + "documents.view_taskattributes", + "documents.view_paperlesstask", + "django_q.add_success", + "documents.view_uisettings", + "auth.change_user", + "admin.delete_logentry", + "django_celery_results.change_taskresult", + "django_q.change_schedule", + "django_celery_results.delete_taskresult", + "paperless_mail.add_mailaccount", + "auth.change_group", + "documents.add_note", + "paperless_mail.delete_mailaccount", + "authtoken.delete_tokenproxy", + "guardian.delete_groupobjectpermission", + "contenttypes.delete_contenttype", + "documents.change_correspondent", + "authtoken.delete_token", + "documents.delete_documenttype", + "django_q.change_ormq", + "documents.change_savedviewfilterrule", + "auth.delete_group", + "documents.add_documenttype", + "django_q.change_success", + "documents.delete_tag", + "documents.change_note", + "django_q.delete_task", + "documents.add_savedviewfilterrule", + "django_q.view_task", + "paperless_mail.add_mailrule", + "paperless_mail.view_mailaccount", + "documents.add_frontendsettings", + "sessions.change_session", + "documents.view_savedview", + "authtoken.add_tokenproxy", + "documents.change_tag", + "documents.view_document", + "documents.add_savedview", + "auth.delete_user", + "documents.view_log", + "documents.view_note", + "guardian.change_groupobjectpermission", + "sessions.delete_session", + "django_q.change_failure", + "guardian.change_userobjectpermission", + "documents.change_storagepath", + "documents.delete_document", + "documents.delete_taskattributes", + "django_celery_results.change_groupresult", + "django_q.add_ormq", + "guardian.view_groupobjectpermission", + "admin.change_logentry", + "django_q.delete_schedule", + "documents.delete_paperlesstask", + "django_q.view_ormq", + "documents.change_paperlesstask", + "guardian.delete_userobjectpermission", + "auth.view_permission", + "auth.view_user", + "django_q.add_schedule", + "authtoken.change_token", + "guardian.add_groupobjectpermission", + "documents.view_documenttype", + "documents.change_log", + "paperless_mail.delete_mailrule", + "auth.view_group", + "authtoken.view_token", + "admin.view_logentry", + "django_celery_results.view_chordcounter", + "django_celery_results.view_groupresult", + "documents.view_storagepath", + "documents.add_storagepath", + "django_celery_results.add_groupresult", + "documents.view_tag", + "guardian.view_userobjectpermission", + "documents.delete_correspondent", + "documents.add_tag", + "documents.delete_savedviewfilterrule", + "documents.add_correspondent", + "authtoken.view_tokenproxy", + "documents.delete_frontendsettings", + "django_celery_results.delete_chordcounter", + "django_q.change_task", + "documents.add_taskattributes", + "documents.delete_storagepath", + "sessions.add_session", + "documents.add_uisettings", + "documents.change_taskattributes", + "documents.delete_uisettings", + "django_q.delete_ormq", + "auth.change_permission", + "documents.view_savedviewfilterrule", + "documents.change_frontendsettings", + "documents.change_documenttype", + "documents.view_correspondent", + "auth.add_user", + "paperless_mail.change_mailaccount", + "documents.add_paperlesstask", + "django_q.view_success", + "django_celery_results.delete_groupresult", + "documents.delete_savedview", + "authtoken.change_tokenproxy", + "documents.view_frontendsettings", + "authtoken.add_token", + "django_celery_results.add_chordcounter", + "contenttypes.change_contenttype", + "admin.add_logentry", + "django_q.delete_failure", + "documents.change_uisettings", + "django_q.view_failure", + "documents.add_log", + "documents.change_savedview", + "paperless_mail.view_mailrule", + "django_q.view_schedule", + "documents.change_document", + "django_celery_results.change_chordcounter", + "documents.add_document", + "django_celery_results.view_taskresult", + "contenttypes.add_contenttype", + "django_q.delete_success", + "documents.delete_note", + "django_q.add_failure", + "guardian.add_userobjectpermission", + "sessions.view_session", + "contenttypes.view_contenttype", + "auth.add_permission", + "documents.delete_log", + "django_q.add_task", + "auth.add_group" + ] +} diff --git a/packages/mock_server/fixtures/users.json b/packages/mock_server/fixtures/users.json new file mode 100644 index 0000000..9be8628 --- /dev/null +++ b/packages/mock_server/fixtures/users.json @@ -0,0 +1,461 @@ +{ + "count": 4, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "username": "admin", + "password": "**********", + "email": "test@test.com", + "first_name": "", + "last_name": "", + "date_joined": "2022-02-14T23:11:09.103293Z", + "is_staff": true, + "is_active": true, + "is_superuser": true, + "groups": [], + "user_permissions": [], + "inherited_permissions": [ + "auth.delete_permission", + "paperless_mail.change_mailrule", + "django_celery_results.add_taskresult", + "documents.view_taskattributes", + "documents.view_paperlesstask", + "django_q.add_success", + "documents.view_uisettings", + "auth.change_user", + "admin.delete_logentry", + "django_celery_results.change_taskresult", + "django_q.change_schedule", + "django_celery_results.delete_taskresult", + "paperless_mail.add_mailaccount", + "auth.change_group", + "documents.add_note", + "paperless_mail.delete_mailaccount", + "authtoken.delete_tokenproxy", + "guardian.delete_groupobjectpermission", + "contenttypes.delete_contenttype", + "documents.change_correspondent", + "authtoken.delete_token", + "documents.delete_documenttype", + "django_q.change_ormq", + "documents.change_savedviewfilterrule", + "auth.delete_group", + "documents.add_documenttype", + "django_q.change_success", + "documents.delete_tag", + "documents.change_note", + "django_q.delete_task", + "documents.add_savedviewfilterrule", + "django_q.view_task", + "paperless_mail.add_mailrule", + "paperless_mail.view_mailaccount", + "documents.add_frontendsettings", + "sessions.change_session", + "documents.view_savedview", + "authtoken.add_tokenproxy", + "documents.change_tag", + "documents.view_document", + "documents.add_savedview", + "auth.delete_user", + "documents.view_log", + "documents.view_note", + "guardian.change_groupobjectpermission", + "sessions.delete_session", + "django_q.change_failure", + "guardian.change_userobjectpermission", + "documents.change_storagepath", + "documents.delete_document", + "documents.delete_taskattributes", + "django_celery_results.change_groupresult", + "django_q.add_ormq", + "guardian.view_groupobjectpermission", + "admin.change_logentry", + "django_q.delete_schedule", + "documents.delete_paperlesstask", + "django_q.view_ormq", + "documents.change_paperlesstask", + "guardian.delete_userobjectpermission", + "auth.view_permission", + "auth.view_user", + "django_q.add_schedule", + "authtoken.change_token", + "guardian.add_groupobjectpermission", + "documents.view_documenttype", + "documents.change_log", + "paperless_mail.delete_mailrule", + "auth.view_group", + "authtoken.view_token", + "admin.view_logentry", + "django_celery_results.view_chordcounter", + "django_celery_results.view_groupresult", + "documents.view_storagepath", + "documents.add_storagepath", + "django_celery_results.add_groupresult", + "documents.view_tag", + "guardian.view_userobjectpermission", + "documents.delete_correspondent", + "documents.add_tag", + "documents.delete_savedviewfilterrule", + "documents.add_correspondent", + "authtoken.view_tokenproxy", + "documents.delete_frontendsettings", + "django_celery_results.delete_chordcounter", + "django_q.change_task", + "documents.add_taskattributes", + "documents.delete_storagepath", + "sessions.add_session", + "documents.add_uisettings", + "documents.change_taskattributes", + "documents.delete_uisettings", + "django_q.delete_ormq", + "auth.change_permission", + "documents.view_savedviewfilterrule", + "documents.change_frontendsettings", + "documents.change_documenttype", + "documents.view_correspondent", + "auth.add_user", + "paperless_mail.change_mailaccount", + "documents.add_paperlesstask", + "django_q.view_success", + "django_celery_results.delete_groupresult", + "documents.delete_savedview", + "authtoken.change_tokenproxy", + "documents.view_frontendsettings", + "authtoken.add_token", + "django_celery_results.add_chordcounter", + "contenttypes.change_contenttype", + "admin.add_logentry", + "django_q.delete_failure", + "documents.change_uisettings", + "django_q.view_failure", + "documents.add_log", + "documents.change_savedview", + "paperless_mail.view_mailrule", + "django_q.view_schedule", + "documents.change_document", + "django_celery_results.change_chordcounter", + "documents.add_document", + "django_celery_results.view_taskresult", + "contenttypes.add_contenttype", + "django_q.delete_success", + "documents.delete_note", + "django_q.add_failure", + "guardian.add_userobjectpermission", + "sessions.view_session", + "contenttypes.view_contenttype", + "auth.add_permission", + "documents.delete_log", + "django_q.add_task", + "auth.add_group" + ] + }, + { + "id": 15, + "username": "test", + "password": "**********", + "first_name": "", + "last_name": "", + "date_joined": "2022-11-23T08:30:54Z", + "is_staff": true, + "is_active": true, + "is_superuser": false, + "groups": [ + 1 + ], + "user_permissions": [ + "add_group", + "change_group", + "delete_group", + "view_group", + "add_permission", + "change_permission", + "delete_permission", + "view_permission", + "add_token", + "change_token", + "delete_token", + "view_token", + "add_tokenproxy", + "change_tokenproxy", + "delete_tokenproxy", + "view_tokenproxy", + "add_contenttype", + "change_contenttype", + "delete_contenttype", + "view_contenttype", + "add_chordcounter", + "change_chordcounter", + "delete_chordcounter", + "view_chordcounter", + "add_groupresult", + "change_groupresult", + "delete_groupresult", + "view_groupresult", + "add_taskresult", + "change_taskresult", + "delete_taskresult", + "view_taskresult", + "add_failure", + "change_failure", + "delete_failure", + "view_failure", + "add_ormq", + "change_ormq", + "delete_ormq", + "view_ormq", + "add_schedule", + "change_schedule", + "delete_schedule", + "view_schedule", + "add_success", + "change_success", + "delete_success", + "view_success", + "add_task", + "change_task", + "delete_task", + "view_task", + "add_note", + "change_note", + "delete_note", + "view_note", + "add_frontendsettings", + "change_frontendsettings", + "delete_frontendsettings", + "view_frontendsettings", + "add_log", + "change_log", + "delete_log", + "view_log", + "add_savedviewfilterrule", + "change_savedviewfilterrule", + "delete_savedviewfilterrule", + "view_savedviewfilterrule", + "add_taskattributes", + "change_taskattributes", + "delete_taskattributes", + "view_taskattributes", + "add_session", + "change_session", + "delete_session", + "view_session" + ], + "inherited_permissions": [ + "auth.delete_permission", + "django_celery_results.add_taskresult", + "documents.view_taskattributes", + "django_q.add_ormq", + "django_q.add_success", + "django_q.delete_schedule", + "django_q.view_ormq", + "auth.view_permission", + "django_q.add_schedule", + "django_celery_results.change_taskresult", + "django_q.change_schedule", + "django_celery_results.delete_taskresult", + "authtoken.change_token", + "auth.change_group", + "documents.add_note", + "authtoken.delete_tokenproxy", + "documents.view_documenttype", + "contenttypes.delete_contenttype", + "documents.change_correspondent", + "authtoken.delete_token", + "documents.change_log", + "auth.view_group", + "authtoken.view_token", + "django_celery_results.view_chordcounter", + "django_celery_results.view_groupresult", + "documents.delete_documenttype", + "django_q.change_ormq", + "documents.change_savedviewfilterrule", + "django_celery_results.add_groupresult", + "auth.delete_group", + "documents.add_documenttype", + "django_q.change_success", + "auth.add_permission", + "documents.delete_correspondent", + "documents.delete_savedviewfilterrule", + "documents.add_correspondent", + "authtoken.view_tokenproxy", + "documents.delete_frontendsettings", + "django_celery_results.delete_chordcounter", + "documents.add_taskattributes", + "django_q.change_task", + "sessions.add_session", + "documents.change_taskattributes", + "documents.change_note", + "django_q.delete_task", + "django_q.delete_ormq", + "auth.change_permission", + "documents.add_savedviewfilterrule", + "django_q.view_task", + "documents.view_savedviewfilterrule", + "documents.change_frontendsettings", + "documents.change_documenttype", + "documents.view_correspondent", + "django_q.view_success", + "documents.add_frontendsettings", + "django_celery_results.delete_groupresult", + "documents.delete_savedview", + "authtoken.change_tokenproxy", + "documents.view_frontendsettings", + "authtoken.add_token", + "sessions.change_session", + "django_celery_results.add_chordcounter", + "documents.view_savedview", + "contenttypes.change_contenttype", + "django_q.delete_failure", + "authtoken.add_tokenproxy", + "documents.view_document", + "documents.add_savedview", + "django_q.view_failure", + "documents.view_note", + "documents.view_log", + "documents.add_log", + "documents.change_savedview", + "django_q.view_schedule", + "documents.change_document", + "django_celery_results.change_chordcounter", + "documents.add_document", + "sessions.delete_session", + "django_q.change_failure", + "django_celery_results.view_taskresult", + "contenttypes.add_contenttype", + "django_q.delete_success", + "documents.delete_note", + "django_q.add_failure", + "sessions.view_session", + "contenttypes.view_contenttype", + "documents.delete_taskattributes", + "documents.delete_document", + "documents.delete_log", + "django_q.add_task", + "django_celery_results.change_groupresult", + "auth.add_group" + ] + }, + { + "id": 6, + "username": "testuser", + "password": "**********", + "email": "test3@test.com", + "first_name": "", + "last_name": "", + "date_joined": "2022-11-16T04:14:20.484914Z", + "is_staff": false, + "is_active": true, + "is_superuser": false, + "groups": [ + 1, + 6 + ], + "user_permissions": [ + "add_logentry", + "change_logentry", + "delete_logentry", + "view_logentry" + ], + "inherited_permissions": [ + "auth.delete_permission", + "django_celery_results.add_taskresult", + "documents.view_taskattributes", + "django_q.add_ormq", + "django_q.add_success", + "django_q.delete_schedule", + "django_q.view_ormq", + "auth.change_user", + "auth.view_permission", + "auth.view_user", + "django_q.add_schedule", + "django_celery_results.change_taskresult", + "django_q.change_schedule", + "django_celery_results.delete_taskresult", + "authtoken.change_token", + "auth.change_group", + "documents.add_note", + "authtoken.delete_tokenproxy", + "documents.view_documenttype", + "contenttypes.delete_contenttype", + "documents.change_correspondent", + "authtoken.delete_token", + "documents.change_log", + "auth.view_group", + "authtoken.view_token", + "django_celery_results.view_chordcounter", + "django_celery_results.view_groupresult", + "documents.delete_documenttype", + "django_q.change_ormq", + "documents.change_savedviewfilterrule", + "django_celery_results.add_groupresult", + "auth.delete_group", + "documents.add_documenttype", + "django_q.change_success", + "auth.add_permission", + "documents.delete_correspondent", + "documents.delete_savedviewfilterrule", + "documents.add_correspondent", + "authtoken.view_tokenproxy", + "documents.delete_frontendsettings", + "django_celery_results.delete_chordcounter", + "documents.add_taskattributes", + "django_q.change_task", + "sessions.add_session", + "documents.change_taskattributes", + "documents.change_note", + "django_q.delete_task", + "django_q.delete_ormq", + "auth.change_permission", + "documents.add_savedviewfilterrule", + "django_q.view_task", + "documents.view_savedviewfilterrule", + "documents.change_frontendsettings", + "documents.change_documenttype", + "documents.view_correspondent", + "auth.add_user", + "django_q.view_success", + "documents.add_frontendsettings", + "django_celery_results.delete_groupresult", + "documents.delete_savedview", + "authtoken.change_tokenproxy", + "documents.view_frontendsettings", + "authtoken.add_token", + "sessions.change_session", + "django_celery_results.add_chordcounter", + "documents.view_savedview", + "contenttypes.change_contenttype", + "django_q.delete_failure", + "authtoken.add_tokenproxy", + "documents.view_document", + "documents.add_savedview", + "django_q.view_failure", + "documents.view_note", + "documents.view_log", + "auth.delete_user", + "documents.add_log", + "documents.change_savedview", + "django_q.view_schedule", + "documents.change_document", + "django_celery_results.change_chordcounter", + "documents.add_document", + "sessions.delete_session", + "django_q.change_failure", + "django_celery_results.view_taskresult", + "contenttypes.add_contenttype", + "django_q.delete_success", + "documents.delete_note", + "django_q.add_failure", + "sessions.view_session", + "contenttypes.view_contenttype", + "documents.delete_taskattributes", + "documents.delete_document", + "documents.delete_log", + "django_q.add_task", + "django_celery_results.change_groupresult", + "auth.add_group" + ] + } + ] +} diff --git a/packages/mock_server/lib/mock_server.dart b/packages/mock_server/lib/mock_server.dart new file mode 100644 index 0000000..281209c --- /dev/null +++ b/packages/mock_server/lib/mock_server.dart @@ -0,0 +1,284 @@ +library mock_server; + +import 'dart:convert'; +import 'dart:math'; +import 'package:http/http.dart' as http; + +import 'package:logging/logging.dart'; + +import 'package:shelf/shelf.dart'; + +import 'package:shelf/shelf_io.dart' as shelf_io; + +import 'package:shelf_router/shelf_router.dart' as shelf_router; + +import 'package:flutter/services.dart' show rootBundle; +import 'dart:convert'; + +Logger log = Logger('LocalMockApiServer'); + +class LocalMockApiServer { + static final host = 'localhost'; + + static final port = 3131; + + static get baseUrl => 'http://$host:$port/'; + + late shelf_router.Router app; + Future> loadFixture(String name) async { + var fixture = + await rootBundle.loadString('packages/mock_server/fixtures/$name.json'); + return json.decode(fixture); + } + + LocalMockApiServer() { + app = shelf_router.Router(); + + Map createdTags = {}; + + app.get('/api/', (Request req) async { + log.info('Responding to /api'); + return JsonMockResponse.ok({}); + }); + + app.post('/api/token/', (Request req) async { + log.info('Responding to /api/token/'); + var body = await req.bodyJsonMap(); + if (body?['username'] == 'admin' && body?['password'] == 'test') { + return JsonMockResponse.ok({'token': 'testToken'}); + } else { + return Response.unauthorized('Unauthorized'); + } + }); + + app.get('/api/ui_settings/', (Request req) async { + log.info('Responding to /api/ui_settings/'); + var data = await loadFixture('ui_settings'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/users//', (Request req, String userId) async { + log.info('Responding to /api/users//'); + var data = await loadFixture('user-1'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/users/', (Request req, String userId) async { + log.info('Responding to /api/users/'); + var data = await loadFixture('users'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/groups/', (Request req, String userId) async { + log.info('Responding to /api/groups/'); + var data = await loadFixture('groups'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/correspondents/', (Request req) async { + log.info('Responding to /api/correspondents/'); + var data = await loadFixture('correspondents'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/document_types/', (Request req) async { + log.info('Responding to /api/document_types/'); + var data = await loadFixture('doc_types'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/tags/', (Request req) async { + log.info('Responding to /api/tags/'); + if (createdTags.isEmpty) { + var data = await loadFixture("tags"); + createdTags = data; + } + return JsonMockResponse.ok(createdTags); + }); + + app.post('/api/tags/', (Request req) async { + log.info('Responding to POST /api/tags/'); + var body = await req.bodyJsonMap(); + var data = { + "id": Random().nextInt(200), + "slug": body?['name'], + "name": body?['name'], + "color": body?['color'], + "text_color": "#000000", + "match": "", + "matching_algorithm": body?['matching_algorithm'], + "is_insensitive": body?['is_insensitive'], + "is_inbox_tag": false, + "owner": 1, + "user_can_change": true, + "document_count": Random().nextInt(200) + }; + (createdTags['results'] as List).add(data); + return Response(201, + body: jsonEncode(data), + headers: {'Content-Type': 'application/json'}, + encoding: null, + context: null); + }); + + app.put('/api/tags//', (Request req, String tagId) async { + log.info('Responding to PUT /api/tags//'); + var body = await req.bodyJsonMap(); + var data = { + "id": body?['id'], + "slug": body?['name'], + "name": body?['name'], + "color": body?['color'], + "text_color": "#000000", + "match": "", + "matching_algorithm": body?['matching_algorithm'], + "is_insensitive": body?['is_insensitive'], + "is_inbox_tag": false, + "owner": 1, + "user_can_change": true, + "document_count": Random().nextInt(200) + }; + var index = (createdTags['results'] as List) + .indexWhere((element) => element['id'] == body?['id']); + (createdTags['results'] as List)[index] = data; + return Response(200, + body: jsonEncode(data), + headers: {'Content-Type': 'application/json'}, + encoding: null, + context: null); + }); + + app.delete('/api/tags//', (Request req, String tagId) async { + log.info('Responding to PUT /api/tags//'); + (createdTags['results'] as List) + .removeWhere((element) => element['id'] == tagId); + return Response(204, + body: null, + headers: {'Content-Type': 'application/json'}, + encoding: null, + context: null); + }); + + app.get('/api/storage_paths/', (Request req) async { + log.info('Responding to /api/storage_paths/'); + var data = await loadFixture('storage_paths'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/storage_paths/', (Request req) async { + log.info('Responding to /api/storage_paths/'); + var data = await loadFixture('storage_paths'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/saved_views/', (Request req) async { + log.info('Responding to /api/saved_views/'); + var data = await loadFixture('saved_views'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/documents/', (Request req) async { + log.info('Responding to /api/documents/'); + var data = await loadFixture('documents'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/documents//thumb/', (Request req, String docId) async { + log.info('Responding to /api/documents//thumb/'); + var thumb = await rootBundle + .load('packages/mock_server/fixtures/lorem-ipsum.png'); + try { + var resp = Response.ok( + http.ByteStream.fromBytes(thumb.buffer.asInt8List()), + headers: {'Content-Type': 'image/png'}, + ); + return resp; + } catch (e) { + return null; + } + }); + + app.get('/api/documents//metadata/', + (Request req, String docId) async { + log.info('Responding to /api/documents//metadata/'); + var data = await loadFixture('metadata'); + return JsonMockResponse.ok(data); + }); + + //This is not yet used in the app + app.get('/api/documents//suggestions/', + (Request req, String docId) async { + log.info('Responding to /api/documents//suggestions/'); + var data = await loadFixture('suggestions'); + return JsonMockResponse.ok(data); + }); + + //This is not yet used in the app + app.get('/api/documents//notes/', (Request req, String docId) async { + log.info('Responding to /api/documents//notes/'); + var data = await loadFixture('notes'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/tasks/', (Request req) async { + log.info('Responding to /api/tasks/'); + var data = await loadFixture('tasks'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/statistics/', (Request req) async { + log.info('Responding to /api/statistics/'); + var data = await loadFixture('statistics'); + return JsonMockResponse.ok(data); + }); + + app.get('/api/statistics/', (Request req) async { + log.info('Responding to /api/statistics/'); + var data = await loadFixture('statistics'); + return JsonMockResponse.ok(data); + }); + } + + Future start() async { + log.info('starting...'); + + var handler = const Pipeline().addMiddleware( + logRequests(logger: (message, isError) { + if (isError) + log.severe(message); + else + log.info(message); + }), + ).addHandler(app); + + var server = await shelf_io.serve(handler, host, port); + + server.autoCompress = true; + + log.info('serving on: $baseUrl'); + } +} + +extension on Request { + Future bodyJsonValue(String param) async { + return jsonDecode(await this.readAsString())?[param]; + } + + Future bodyJsonMap() async { + return jsonDecode(await this.readAsString()); + } + + String? get accessToken => + this.headers['Authorization']?.split('Bearer ').last; +} + +extension JsonMockResponse on Response { + static ok(T json, {int delay = 800}) async { + await Future.delayed(Duration(milliseconds: delay)); // Emulate lag + + return Response.ok( + jsonEncode(json), + headers: {'Content-Type': 'application/json'}, + ); + } +} diff --git a/packages/mock_server/pubspec.yaml b/packages/mock_server/pubspec.yaml new file mode 100644 index 0000000..0808b48 --- /dev/null +++ b/packages/mock_server/pubspec.yaml @@ -0,0 +1,59 @@ +name: mock_server +description: A new Flutter package project. +version: 0.0.1 +homepage: + +environment: + sdk: '>=3.0.0 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + shelf: ^1.4.1 + shelf_router: ^1.1.4 + logging: ^1.1.1 + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + assets: + - fixtures/ + - fixtures/ui_settings.json + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/paperless_api/lib/config/hive/hive_type_ids.dart b/packages/paperless_api/lib/config/hive/hive_type_ids.dart index 3568647..a931473 100644 --- a/packages/paperless_api/lib/config/hive/hive_type_ids.dart +++ b/packages/paperless_api/lib/config/hive/hive_type_ids.dart @@ -30,6 +30,7 @@ class PaperlessApiHiveTypeIds { static const int groupModel = 124; static const int permissions = 125; static const int userModelv2 = 126; + static const int usersAndGroupsPermissions = 127; } void registerPaperlessApiHiveTypeAdapters() { diff --git a/packages/paperless_api/lib/src/models/permissions/permissions.dart b/packages/paperless_api/lib/src/models/permissions/permissions.dart index ea0d489..3530f8b 100644 --- a/packages/paperless_api/lib/src/models/permissions/permissions.dart +++ b/packages/paperless_api/lib/src/models/permissions/permissions.dart @@ -1,6 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hive/hive.dart'; import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_api/src/models/permissions/users_and_groups_permissions.dart'; part 'permissions.freezed.dart'; part 'permissions.g.dart'; @@ -9,8 +10,8 @@ part 'permissions.g.dart'; @freezed class Permissions with _$Permissions { const factory Permissions({ - @HiveField(0) @Default([]) List view, - @HiveField(1) @Default([]) List change, + @HiveField(0) required UsersAndGroupsPermissions view, + @HiveField(1) required UsersAndGroupsPermissions change, }) = _Permissions; factory Permissions.fromJson(Map json) => _$PermissionsFromJson(json); diff --git a/packages/paperless_api/lib/src/models/permissions/users_and_groups_permissions.dart b/packages/paperless_api/lib/src/models/permissions/users_and_groups_permissions.dart new file mode 100644 index 0000000..326005e --- /dev/null +++ b/packages/paperless_api/lib/src/models/permissions/users_and_groups_permissions.dart @@ -0,0 +1,17 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:paperless_api/paperless_api.dart'; + +part 'users_and_groups_permissions.freezed.dart'; +part 'users_and_groups_permissions.g.dart'; + +@HiveType(typeId: PaperlessApiHiveTypeIds.usersAndGroupsPermissions) +@freezed +class UsersAndGroupsPermissions with _$UsersAndGroupsPermissions { + const factory UsersAndGroupsPermissions({ + @HiveField(0) @Default([]) List users, + @HiveField(1) @Default([]) List groups, + }) = _UsersAndGroupsPermissions; + + factory UsersAndGroupsPermissions.fromJson(Map json) => _$UsersAndGroupsPermissionsFromJson(json); +} diff --git a/packages/paperless_api/lib/src/models/user_model.dart b/packages/paperless_api/lib/src/models/user_model.dart index 340f5f4..56bc1c1 100644 --- a/packages/paperless_api/lib/src/models/user_model.dart +++ b/packages/paperless_api/lib/src/models/user_model.dart @@ -16,7 +16,7 @@ class UserModel with _$UserModel { const factory UserModel.v3({ @HiveField(0) required int id, @HiveField(1) required String username, - @HiveField(2) required String email, + @HiveField(2) String? email, @HiveField(3) String? firstName, @HiveField(4) String? lastName, @HiveField(5) DateTime? dateJoined, diff --git a/pubspec.lock b/pubspec.lock index d3d982b..4cc75b4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -800,6 +800,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.13.5" + http_methods: + dependency: transitive + description: + name: http_methods + sha256: "6bccce8f1ec7b5d701e7921dca35e202d425b57e317ba1a37f2638590e29e566" + url: "https://pub.dev" + source: hosted + version: "1.1.1" http_multi_server: dependency: transitive description: @@ -981,6 +989,13 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + mock_server: + dependency: "direct dev" + description: + path: "packages/mock_server" + relative: true + source: path + version: "0.0.1" mockito: dependency: "direct dev" description: @@ -1376,10 +1391,10 @@ packages: dependency: transitive description: name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_packages_handler: dependency: transitive description: @@ -1388,6 +1403,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + shelf_router: + dependency: transitive + description: + name: shelf_router + sha256: f5e5d492440a7fb165fe1e2e1a623f31f734d3370900070b2b1e0d0428d59864 + url: "https://pub.dev" + source: hosted + version: "1.1.4" shelf_static: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 46f6943..3c73fa8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -115,6 +115,8 @@ dev_dependencies: auto_route_generator: ^5.0.3 freezed: ^2.3.3 hive_generator: ^2.0.0 + mock_server: + path: packages/mock_server # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec