diff --git a/src-ui/.gitignore b/src-ui/.gitignore index 963d2f8ee..5f427c51c 100644 --- a/src-ui/.gitignore +++ b/src-ui/.gitignore @@ -45,4 +45,7 @@ testem.log # System Files .DS_Store Thumbs.db + +# Cypress cypress/videos/**/* +cypress/screenshots/**/* diff --git a/src-ui/cypress/fixtures/correspondents/correspondents.json b/src-ui/cypress/fixtures/correspondents/correspondents.json new file mode 100644 index 000000000..fe9fa1d5f --- /dev/null +++ b/src-ui/cypress/fixtures/correspondents/correspondents.json @@ -0,0 +1 @@ +{"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":"michael-shamoon","name":"Michael Shamoon","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/src-ui/cypress/fixtures/document_types/doctypes.json b/src-ui/cypress/fixtures/document_types/doctypes.json new file mode 100644 index 000000000..36c75f2ff --- /dev/null +++ b/src-ui/cypress/fixtures/document_types/doctypes.json @@ -0,0 +1 @@ +{"count":1,"next":null,"previous":null,"results":[{"id":1,"slug":"test","name":"Test Doc Type","match":"","matching_algorithm":1,"is_insensitive":true,"document_count":0}]} diff --git a/src-ui/cypress/fixtures/documents/1/metadata.json b/src-ui/cypress/fixtures/documents/1/metadata.json new file mode 100644 index 000000000..f5bfd9531 --- /dev/null +++ b/src-ui/cypress/fixtures/documents/1/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/src-ui/cypress/fixtures/documents/1/suggestions.json b/src-ui/cypress/fixtures/documents/1/suggestions.json new file mode 100644 index 000000000..d9888dbf3 --- /dev/null +++ b/src-ui/cypress/fixtures/documents/1/suggestions.json @@ -0,0 +1 @@ +{"correspondents":[],"tags":[3],"document_types":[1]} diff --git a/src-ui/cypress/fixtures/documents/documents.json b/src-ui/cypress/fixtures/documents/documents.json index 984e2f8fc..618a3f07c 100644 --- a/src-ui/cypress/fixtures/documents/documents.json +++ b/src-ui/cypress/fixtures/documents/documents.json @@ -1 +1 @@ -{"count":1,"next":null,"previous":null,"results":[{"id":1,"correspondent":null,"document_type":null,"title":"lorem-ipsum","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":[],"created":"2022-03-22T07:24:18Z","modified":"2022-03-22T07:24:23.264859Z","added":"2022-03-22T07:24:22.922631Z","archive_serial_number":null,"original_file_name":"2022-03-22 lorem-ipsum.pdf","archived_file_name":"2022-03-22 lorem-ipsum.pdf"}]} \ No newline at end of file +{"count":3,"next":null,"previous":null,"results":[{"id":1,"correspondent":9,"document_type":1,"title":"lorem-ipsum","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","modified":"2022-03-22T07:24:23.264859Z","added":"2022-03-22T07:24:22.922631Z","archive_serial_number":null,"original_file_name":"2022-03-22 lorem-ipsum.pdf","archived_file_name":"2022-03-22 lorem-ipsum.pdf"},{"id":2,"correspondent":null,"document_type":null,"title":"lorem-ipsum","content":"Test document PDF","tags":[],"created":"2022-03-23T07:24:18Z","modified":"2022-03-23T07:24:23.264859Z","added":"2022-03-23T07:24:22.922631Z","archive_serial_number":null,"original_file_name":"2022-03-23 lorem-ipsum.pdf","archived_file_name":"2022-03-23 lorem-ipsum.pdf"},{"id":3,"correspondent":null,"document_type":1,"title":"lorem-ipsum","content":"Test document PDF","tags":[2],"created":"2022-03-24T07:24:18Z","modified":"2022-03-24T07:24:23.264859Z","added":"2022-03-24T07:24:22.922631Z","archive_serial_number":null,"original_file_name":"2022-03-24 lorem-ipsum.pdf","archived_file_name":"2022-03-24 lorem-ipsum.pdf"}]} diff --git a/src-ui/cypress/fixtures/saved_views/savedviews.json b/src-ui/cypress/fixtures/saved_views/savedviews.json new file mode 100644 index 000000000..003bd900a --- /dev/null +++ b/src-ui/cypress/fixtures/saved_views/savedviews.json @@ -0,0 +1 @@ +{"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/src-ui/cypress/fixtures/tags/tags.json b/src-ui/cypress/fixtures/tags/tags.json new file mode 100644 index 000000000..e48049f93 --- /dev/null +++ b/src-ui/cypress/fixtures/tags/tags.json @@ -0,0 +1 @@ +{"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/src-ui/cypress/integration/document-detail.spec.ts b/src-ui/cypress/integration/document-detail.spec.ts new file mode 100644 index 000000000..9ff566760 --- /dev/null +++ b/src-ui/cypress/integration/document-detail.spec.ts @@ -0,0 +1,64 @@ +describe('document-detail', () => { + beforeEach(() => { + this.modifiedDocuments = [] + + cy.fixture('documents/documents.json').then((documentsJson) => { + cy.intercept('GET', 'http://localhost:8000/api/documents/1/', (req) => { + let response = { ...documentsJson } + response = response.results.find((d) => d.id == 1) + req.reply(response) + }) + }) + + cy.intercept('PUT', 'http://localhost:8000/api/documents/1/', (req) => { + this.modifiedDocuments.push(req.body) // store this for later + req.reply({ result: 'OK' }) + }).as('saveDoc') + + cy.intercept('http://localhost:8000/api/documents/1/metadata/', { + fixture: 'documents/1/metadata.json', + }) + + cy.intercept('http://localhost:8000/api/documents/1/suggestions/', { + fixture: 'documents/1/suggestions.json', + }) + + cy.intercept('http://localhost:8000/api/saved_views/*', { + fixture: 'saved_views/savedviews.json', + }) + + cy.intercept('http://localhost:8000/api/tags/*', { + fixture: 'tags/tags.json', + }) + + cy.intercept('http://localhost:8000/api/correspondents/*', { + fixture: 'correspondents/correspondents.json', + }) + + cy.intercept('http://localhost:8000/api/document_types/*', { + fixture: 'document_types/doctypes.json', + }) + + cy.viewport(1024, 1024) + cy.visit('/documents/1/') + }) + + it('should activate / deactivate save button when changes are saved', () => { + cy.contains('button', 'Save').should('be.disabled') + cy.get('app-input-text[formcontrolname="title"]') + .type(' additional') + .wait(1500) // this delay is for frontend debounce + cy.contains('button', 'Save').should('not.be.disabled') + }) + + it('should warn on unsaved changes', () => { + cy.get('app-input-text[formcontrolname="title"]') + .type(' additional') + .wait(1500) // this delay is for frontend debounce + cy.get('button[title="Close"]').click() + cy.contains('You have unsaved changes') + cy.contains('button', 'Cancel').click().wait(150) + cy.contains('button', 'Save').click().wait('@saveDoc').wait(2000) // navigates away after saving + cy.contains('You have unsaved changes').should('not.exist') + }) +}) diff --git a/src-ui/cypress/integration/documents-list.spec.ts b/src-ui/cypress/integration/documents-list.spec.ts index 8d8b21009..5b923ed2f 100644 --- a/src-ui/cypress/integration/documents-list.spec.ts +++ b/src-ui/cypress/integration/documents-list.spec.ts @@ -1,20 +1,143 @@ describe('documents-list', () => { beforeEach(() => { - cy.intercept('http://localhost:8000/api/documents/*', { - fixture: 'documents/documents.json', - }); + this.bulkEdits = {} + + // mock API methods + cy.fixture('documents/documents.json').then((documentsJson) => { + // bulk edit + cy.intercept( + 'POST', + 'http://localhost:8000/api/documents/bulk_edit/', + (req) => { + this.bulkEdits = req.body // store this for later + req.reply({ result: 'OK' }) + } + ) + + cy.intercept('GET', 'http://localhost:8000/api/documents/*', (req) => { + let response = { ...documentsJson } + + // bulkEdits was set earlier by bulk_edit intercept + if (this.bulkEdits.hasOwnProperty('documents')) { + response.results = response.results.map((d) => { + if ((this.bulkEdits['documents'] as Array).includes(d.id)) { + switch (this.bulkEdits['method']) { + case 'modify_tags': + d.tags = (d.tags as Array).concat([ + this.bulkEdits['parameters']['add_tags'], + ]) + break + case 'set_correspondent': + d.correspondent = + this.bulkEdits['parameters']['correspondent'] + break + case 'set_document_type': + d.document_type = + this.bulkEdits['parameters']['document_type'] + break + } + } + + return d + }) + } else if (req.query.hasOwnProperty('tags__id__all')) { + // filtering e.g. http://localhost:8000/api/documents/?page=1&page_size=50&ordering=-created&tags__id__all=2 + const tag_id = +req.query['tags__id__all'] + response.results = (documentsJson.results as Array).filter((d) => + (d.tags as Array).includes(tag_id) + ) + response.count = response.results.length + } + + req.reply(response) + }) + }) + cy.intercept('http://localhost:8000/api/documents/1/thumb/', { fixture: 'documents/lorem-ipsum.png', - }); + }) - cy.visit('/documents'); - }); + cy.intercept('http://localhost:8000/api/tags/*', { + fixture: 'tags/tags.json', + }) + + cy.intercept('http://localhost:8000/api/correspondents/*', { + fixture: 'correspondents/correspondents.json', + }) + + cy.intercept('http://localhost:8000/api/document_types/*', { + fixture: 'document_types/doctypes.json', + }) + + cy.visit('/documents') + }) it('should show a list of documents rendered as cards with thumbnails', () => { - cy.contains('One document'); - cy.contains('lorem-ipsum'); + cy.contains('3 documents') + cy.contains('lorem-ipsum') cy.get('app-document-card-small:first-of-type img') .invoke('attr', 'src') - .should('eq', 'http://localhost:8000/api/documents/1/thumb/'); - }); -}); + .should('eq', 'http://localhost:8000/api/documents/1/thumb/') + }) + + it('should change to table "details" view', () => { + cy.get('div.btn-group-toggle input[value="details"]').parent().click() + cy.get('table') + }) + + it('should change to large cards view', () => { + cy.get('div.btn-group-toggle input[value="largeCards"]').parent().click() + cy.get('app-document-card-large') + }) + + it('should filter tags', () => { + cy.get('app-filter-editor app-filterable-dropdown[title="Tags"]').within( + () => { + cy.contains('button', 'Tags').click() + cy.contains('button', 'Tag 2').click() + } + ) + cy.contains('One document') + }) + + it('should apply tags', () => { + cy.get('app-document-card-small:first-of-type').click() + cy.get('app-bulk-editor app-filterable-dropdown[title="Tags"]').within( + () => { + cy.contains('button', 'Tags').click() + cy.contains('button', 'Test Tag').click() + cy.contains('button', 'Apply').click() + } + ) + cy.contains('button', 'Confirm').click() + cy.get('app-document-card-small:first-of-type').contains('Test Tag') + }) + + it('should apply correspondent', () => { + cy.get('app-document-card-small:first-of-type').click() + cy.get( + 'app-bulk-editor app-filterable-dropdown[title="Correspondent"]' + ).within(() => { + cy.contains('button', 'Correspondent').click() + cy.contains('button', 'ABC Test Correspondent').click() + cy.contains('button', 'Apply').click() + }) + cy.contains('button', 'Confirm').click() + cy.get('app-document-card-small:first-of-type').contains( + 'ABC Test Correspondent' + ) + }) + + it('should apply document type', () => { + cy.get('app-document-card-small:first-of-type').click() + cy.get( + 'app-bulk-editor app-filterable-dropdown[title="Document type"]' + ).within(() => { + cy.contains('button', 'Document type').click() + cy.contains('button', 'Test Doc Type').click() + cy.contains('button', 'Apply').click() + }) + cy.contains('button', 'Confirm').click() + cy.get('app-document-card-small:first-of-type').contains('Test Doc Type') + }) +}) diff --git a/src-ui/cypress/integration/manage.spec.ts b/src-ui/cypress/integration/manage.spec.ts new file mode 100644 index 000000000..68562a744 --- /dev/null +++ b/src-ui/cypress/integration/manage.spec.ts @@ -0,0 +1,32 @@ +describe('documents-list', () => { + beforeEach(() => { + cy.intercept('http://localhost:8000/api/correspondents/*', { + fixture: 'correspondents/correspondents.json', + }) + cy.intercept('http://localhost:8000/api/tags/*', { + fixture: 'tags/tags.json', + }) + }) + + it('should show a list of correspondents with bottom pagination as well', () => { + cy.visit('/correspondents') + cy.get('tbody').find('tr').its('length').should('eq', 25) + cy.get('ngb-pagination').its('length').should('eq', 2) + }) + + it('should show a list of tags without bottom pagination', () => { + cy.visit('/tags') + cy.get('tbody').find('tr').its('length').should('eq', 8) + cy.get('ngb-pagination').its('length').should('eq', 1) + }) + + it('should show a list of documents filtered by tag', () => { + cy.intercept('http://localhost:8000/api/documents/*', (req) => { + if (req.url.indexOf('tags__id__all=4')) + req.reply({ count: 3, next: null, previous: null, results: [] }) + }) + cy.visit('/tags') + cy.get('tbody').find('button').contains('Documents').first().click() // id = 4 + cy.contains('3 documents') + }) +}) diff --git a/src-ui/cypress/integration/settings.spec.ts b/src-ui/cypress/integration/settings.spec.ts new file mode 100644 index 000000000..0da4aa151 --- /dev/null +++ b/src-ui/cypress/integration/settings.spec.ts @@ -0,0 +1,101 @@ +describe('settings', () => { + beforeEach(() => { + this.modifiedViews = [] + + // mock API methods + cy.fixture('saved_views/savedviews.json').then((savedViewsJson) => { + // saved views PATCH + cy.intercept( + 'PATCH', + 'http://localhost:8000/api/saved_views/*', + (req) => { + this.modifiedViews.push(req.body) // store this for later + req.reply({ result: 'OK' }) + } + ) + + cy.intercept('GET', 'http://localhost:8000/api/saved_views/*', (req) => { + let response = { ...savedViewsJson } + if (this.modifiedViews.length) { + response.results = response.results.map((v) => { + if (this.modifiedViews.find((mv) => mv.id == v.id)) + v = this.modifiedViews.find((mv) => mv.id == v.id) + return v + }) + } + + req.reply(response) + }).as('savedViews') + }) + + cy.fixture('documents/documents.json').then((documentsJson) => { + cy.intercept('GET', 'http://localhost:8000/api/documents/1/', (req) => { + let response = { ...documentsJson } + response = response.results.find((d) => d.id == 1) + req.reply(response) + }) + }) + + cy.intercept('http://localhost:8000/api/documents/1/metadata/', { + fixture: 'documents/1/metadata.json', + }) + + cy.intercept('http://localhost:8000/api/documents/1/suggestions/', { + fixture: 'documents/1/suggestions.json', + }) + + cy.viewport(1024, 1024) + cy.visit('/settings') + cy.wait('@savedViews') + }) + + it('should activate / deactivate save button when settings change and are saved', () => { + cy.contains('button', 'Save').should('be.disabled') + cy.contains('Use system settings').click() + cy.contains('button', 'Save').should('not.be.disabled') + cy.contains('button', 'Save').click() + cy.contains('button', 'Save').should('be.disabled') + }) + + it('should warn on unsaved changes', () => { + cy.contains('Use system settings').click() + cy.contains('a', 'Dashboard').click() + cy.contains('You have unsaved changes') + cy.contains('button', 'Cancel').click() + cy.contains('button', 'Save').click().wait('@savedViews') + cy.contains('a', 'Dashboard').click() + cy.contains('You have unsaved changes').should('not.exist') + }) + + it('should apply appearance changes when set', () => { + cy.contains('Use system settings').click() + cy.get('body').should('not.have.class', 'color-scheme-system') + cy.contains('Enable dark mode').click() + cy.get('body').should('have.class', 'color-scheme-dark') + }) + + it('should remove saved view from sidebar when unset', () => { + cy.contains('a', 'Saved views').click() + cy.get('#show_in_sidebar_1').click() + cy.contains('button', 'Save').click().wait('@savedViews') + cy.contains('li', 'Inbox').should('not.exist') + }) + + it('should remove saved view from dashboard when unset', () => { + cy.contains('a', 'Saved views').click() + cy.get('#show_on_dashboard_1').click() + cy.contains('button', 'Save').click().wait('@savedViews') + cy.visit('/dashboard') + cy.get('app-saved-view-widget').contains('Inbox').should('not.exist') + }) + + it('should change the pdf viewer type', () => { + cy.visit('/documents/1') + cy.get('object[data*="/api/documents/1/preview/"]').should('not.exist') + cy.visit('/settings') + cy.contains('Use PDF viewer provided by the browser').click() + cy.contains('button', 'Save').click().wait('@savedViews').wait(1000) + cy.visit('/documents/1') + cy.get('object[data*="/api/documents/1/preview/"]') + }) +})