def test_list_persons(self): empty = json.loads(self.client.get("/api/read/persons").data) self.assertEqual(len(empty["data"]), 0) persons = [ContributorFactory() for _ in range(8)] for p in persons: librarian.db.session.add(p) inactive = ContributorFactory(lastname="GLadwell", firstname="MAlcolm III", active=False) librarian.db.session.add(inactive) librarian.db.session.flush() expected_person_set = set( [Person(p.lastname, p.firstname) for p in persons]) list_persons = self.client.get("/api/read/persons") data = json.loads(list_persons.data) person_set = set( [Person(p["lastname"], p["firstname"]) for p in data["data"]]) self.assertEqual(expected_person_set, person_set) inactive.active = True librarian.db.session.flush() expected_person_set.add(Person(inactive.lastname, inactive.firstname)) list_persons = self.client.get("/api/read/persons") data = json.loads(list_persons.data) person_set = set( [Person(p["lastname"], p["firstname"]) for p in data["data"]]) self.assertEqual(expected_person_set, person_set)
def test_edit_book_contrib_add(self): self.make_current_user() authors = [ContributorFactory().make_plain_person() for _ in range(3)] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Mumford and Sons", author=authors, publish_year=2016, genre="Fiction") book_id = create_book(librarian.db.session, book, self.admin_user) librarian.db.session.commit() author_role = Role.get_preset_role("Author") book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_authors ]) self.assertEquals(set(authors), author_persons) additional_author = ContributorFactory().make_plain_person() _book_authors = copy.deepcopy(list(book.authors)) _book_authors.append(additional_author) edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, author=_book_authors, publish_year=book.publish_year, genre=book.genre, id=book_id) librarian.db.session.commit() edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_authors ]) self.assertEqual(set(_book_authors), author_persons)
def test_book_adder_duplicate_isbn10(self): """ Switch ISBNs of test_book_adder_duplicate_isbn13. """ self.make_current_user() isbn13 = "1596914696" self.verify_does_not_exist(Book, isbn=isbn13) self.verify_does_not_exist(Genre, name="Academic Nonfiction") self.verify_does_not_exist(Contributor, lastname="Bayard", firstname="Pierre") self.verify_does_not_exist(Contributor, lastname="Mehlman", firstname="Jeffrey") self.verify_does_not_exist(BookCompany, name="Bloomsbury") self.verify_does_not_exist(BookCompany, name="Quebecor World Fairfield") author = [Person(lastname="Bayard", firstname="Pierre")] translator = [Person(lastname="Mehlman", firstname="Jeffrey")] books_you_havent_read = BookRecord( isbn=isbn13, title="How to Talk About Books You Haven't Read", author=author, translator=translator, genre="Academic Nonfiction", publisher="Bloomsbury", printer="Quebecor World Fairfield", publish_year=2007) havent_read_rv = self.client.post( "/api/add/books", data=books_you_havent_read.request_data()) self.verify_inserted(Book, isbn=isbn13) self.verify_inserted(Genre, name="Academic Nonfiction") self.verify_inserted(Contributor, lastname="Bayard", firstname="Pierre") self.verify_inserted(Contributor, lastname="Mehlman", firstname="Jeffrey") self.verify_inserted(BookCompany, name="Bloomsbury") self.verify_inserted(BookCompany, name="Quebecor World Fairfield") books_you_havent_read.isbn = "9781596914698" duplicate = self.client.post("/api/add/books", data=books_you_havent_read.request_data()) self.assertEquals(duplicate._status_code, 409)
def __basic_edit_test(self, book_id): author_role = Role.get_preset_role("Author") book = (librarian.db.session.query(Book).filter( Book.id == book_id).first()) book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) authors = [co.make_plain_person() for co in book_authors] the_deleted = book_authors[-1] author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_authors ]) edited_book_authors = authors[0:-1] edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, author=edited_book_authors, publish_year=book.publish_year, genre=book.genre.name, id=book_id) edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) updated_book_authors = ( librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active) # Just for thoroughness, but in an ideal world BookContribution.active is sufficient .filter(Contributor.active).all()) updated_author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in updated_book_authors ]) self.assertEqual(set(edited_book_authors), updated_author_persons) # Verify that the BookRecord for the "deleted" contribution remains # but inactive. self.verify_inserted(BookContribution, book_id=book_id, contributor_id=the_deleted.id, role_id=author_role.id, active=False) self.verify_inserted(Contributor, id=the_deleted.id, active=False)
def test_book_adder_blank_person(self): self.make_current_user() isbn = fake.isbn() # Check that the relevant records do not exist yet self.verify_does_not_exist(Book, isbn=isbn) self.verify_does_not_exist(Genre, name="io9") self.verify_does_not_exist(BookCompany, name="Scholastic") self.verify_does_not_exist(BookCompany, name="UP Press") author = [Person(lastname="", firstname="")] single_author = BookRecord(isbn=isbn, title="The Carpet Makers", genre="io9", author=author, publisher="Scholastic", printer="UP Press", publish_year=2013) single_rv = self.client.post("/api/add/books", data=single_author.request_data()) self.assertEquals(single_rv._status_code, 400) self.verify_does_not_exist(Book, isbn=isbn) self.verify_does_not_exist(Genre, name="io9") self.verify_does_not_exist(BookCompany, name="Scholastic") self.verify_does_not_exist(BookCompany, name="UP Press")
def test_create_book(self): sample_isbn = "9780306406157" # ensure it does not exist bookq = librarian.db.session.query(Book).filter( Book.isbn == sample_isbn) book = bookq.first() self.assertTrue(book is None) br = BookRecord(isbn=sample_isbn, title="Another Chance for Poland", publisher="Eurosport", author=(Person(lastname="Enrique", firstname="Luis"), ), publish_year=2016, id=314, genre="Test") utils.create_book(librarian.db.session, br, self.admin_user) book = bookq.first() self.assertTrue(book is not None) # Ensure that it has contributors contribs = (librarian.db.session.query(BookContribution).filter( BookContribution.book_id == book.id).all()) self.assertTrue(len(contribs) > 0)
def test_search_isbn(self): search_book = BookRecord(isbn=fake.isbn(), title="Find XYZ Inside", publisher="Creative Awesome", publish_year=2017, author=[Person("Munroe", "Randall")], genre="Test") create_book(librarian.db.session, search_book, self.admin_user) librarian.db.session.flush() results = api.search(search_book.isbn) self.assertEqual(len(results), 1) self.assertEqual(results[0]["isbn"], search_book.isbn)
def test_search_publisher(self): search_book = BookRecord(isbn=fake.isbn(), title="Totally Unrelated to Search Query", publisher="Walnut Publishing", publish_year=2017, author=[Person("Hawking", "Stevie")], genre="Test") create_book(librarian.db.session, search_book, self.admin_user) librarian.db.session.flush() results = api.search("walnut") self.assertEqual(len(results), 1) self.assertEqual(results[0]["isbn"], search_book.isbn)
def test_book_adder_utf8(self): self.make_current_user() isbn = fake.isbn() # Check that the relevant records do not exist yet self.verify_does_not_exist(Book, isbn=isbn) self.verify_does_not_exist(Genre, name="English 12") self.verify_does_not_exist(Contributor, lastname="Pérez-Reverte", firstname="Arturo") self.verify_does_not_exist(Contributor, lastname="de OnÃs", firstname="Harriet") self.verify_does_not_exist(BookCompany, name="Scholastic") self.verify_does_not_exist(BookCompany, name="UP Press") author = [Person(lastname="Pérez-Reverte", firstname="Arturo")] translator = [Person(lastname="de OnÃs", firstname="Harriet")] single_author = BookRecord(isbn=isbn, title="The Club Dumas", genre="English 12", author=author, translator=translator, publisher="Scholastic", printer="UP Press", publish_year=2013) single_rv = self.client.post("/api/add/books", data=single_author.request_data()) self.assertEquals(single_rv._status_code, 200) self.verify_inserted(Book, isbn=isbn) self.verify_inserted(Genre, name="English 12") self.verify_inserted(Contributor, lastname="Pérez-Reverte", firstname="Arturo") self.verify_inserted(BookCompany, name="Scholastic") self.verify_inserted(BookCompany, name="UP Press")
def test_no_printer(self): self.make_current_user() single_author = BookRecord( isbn="9780062330260", title="Trigger Warning", genre="Short Story Collection", author=[Person(lastname="Gaiman", firstname="Neil")], publisher="William Morrow", publish_year=2015) single_rv = self.client.post("/api/add/books", data=single_author.request_data()) self.assertEquals(single_rv._status_code, 200)
def test_deepcopy(self): fake = Faker() fake.add_provider(BookFieldsProvider) authors = [ContributorFactory().make_plain_person() for _ in range(3)] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Firaxis", author=authors, publish_year=2016, genre="Fiction") _book = copy.deepcopy(book) self.assertTrue(book is not _book) original_attrs = book.__dict__ deepcopy_attrs = _book.__dict__ attrs = original_attrs.keys() self.assertEquals(attrs, deepcopy_attrs.keys()) for a in attrs: orig_type = type(original_attrs[a]) copy_type = type(deepcopy_attrs[a]) self.assertTrue(orig_type is copy_type) if a in BookRecord.LIST_TYPES: original_persons = [ Person(**pdict) for pdict in original_attrs[a] ] deepcopy_persons = [ Person(**pdict) for pdict in deepcopy_attrs[a] ] self.assertEquals(set(original_persons), set(deepcopy_persons)) else: self.assertEquals(original_attrs[a], deepcopy_attrs[a]) authors.append(Person(firstname="Sid", lastname="Meier")) _book.authors = frozenset(authors) self.assertNotEquals(book.authors, _book.authors)
def test_multiple_same_names(self): self.make_current_user() Neil_Gaiman = Person(lastname="Gaiman", firstname="Neil") single_author = BookRecord(isbn="9780062330260", title="Trigger Warning", genre="Short Story Collection", author=[Neil_Gaiman, Neil_Gaiman], publisher="William Morrow", publish_year=2015) single_rv = self.client.post("/api/add/books", data=single_author.request_data()) self.assertEquals(200, single_rv.status_code) gaimen = (librarian.db.session.query(Contributor).filter( Contributor.firstname == 'Neil').filter( Contributor.lastname == 'Gaiman').all()) self.assertEquals(1, len(gaimen))
def test_search_contributor(self): search_book = BookRecord( isbn=fake.isbn(), title="Don Quixote", publisher="Instituto Cervantes", publish_year=1957, author=[Person("de Cervantes Saavedra", "Miguel")], genre="Sci-Fi") create_book(librarian.db.session, search_book, self.admin_user) librarian.db.session.flush() results = api.search("Cervantes") self.assertEqual(len(results), 1) self.assertEqual(results[0]["isbn"], search_book.isbn) results = api.search("cervantes") self.assertEqual(len(results), 1) self.assertEqual(results[0]["isbn"], search_book.isbn) results = api.search("miguel de cervantes") self.assertEqual(len(results), 1) self.assertEqual(results[0]["isbn"], search_book.isbn)
def test_extra_whitespace(self): self.make_current_user() self.verify_does_not_exist(Contributor, lastname="de Cervantes", firstname="Miguel") spaced = BookRecord( isbn="0812972104", title="Don Quixote", genre="Fiction", author=[Person(lastname=" de Cervantes ", firstname="Miguel")], publisher="Modern Library", publish_year=2006) spaced_rv = self.client.post("/api/add/books", data=spaced.request_data()) self.assertEquals(200, spaced_rv.status_code) self.verify_inserted(Contributor, lastname="de Cervantes", firstname="Miguel")
def test_factory(self): title = "World Taekwondo Federation Welterweight" publisher_name = "International Olympic Committee" self.verify_does_not_exist(Book, title=title) self.verify_does_not_exist(Contributor, lastname="Tazegul", firstname="Servet") self.verify_does_not_exist(BookCompany, name=publisher_name) factory_made = BookRecord.factory(isbn=fake.isbn(), title=title, publisher=publisher_name, author=[Person("Tazegul", "Servet")], genre="Sports", publish_year=2017) self.verify_inserted(Book, title=title) self.verify_inserted(Contributor, lastname="Tazegul", firstname="Servet") self.verify_inserted(BookCompany, name=publisher_name) self.assertTrue(factory_made is not None) self.assertTrue(factory_made.id is not None)
def test_book_adder_reactivation(self): self.set_current_user(self.admin_user) inactive_contributor = ContributorFactory(lastname="Duffer", firstname="Matt", active=False) librarian.db.session.add(inactive_contributor) librarian.db.session.flush() isbn = fake.isbn() # Check that the relevant records do not exist yet self.verify_does_not_exist(Book, isbn=isbn) self.verify_does_not_exist(Genre, name="Horror") self.verify_does_not_exist(BookCompany, name="Netflix") self.verify_does_not_exist(BookCompany, name="WWW") author = [Person(lastname="Duffer", firstname="Matt")] single_author = BookRecord(isbn=isbn, title="Stranger Things", genre="Horror", author=author, publisher="Netflix", printer="WWW", publish_year=2016) reactivate = self.client.post("/api/add/books", data=single_author.request_data()) self.assertEquals(reactivate._status_code, 200) self.verify_inserted(Book, isbn=isbn) self.verify_inserted(Genre, name="Horror") self.verify_inserted(BookCompany, name="Netflix") self.verify_inserted(BookCompany, name="WWW") self.verify_inserted(Contributor, lastname="Duffer", firstname="Matt", active=True)
def test_same_person_diff_roles(self): self.make_current_user() jtamaki_exists = (librarian.db.session.query(Contributor).filter( Contributor.firstname == "Jillian").filter( Contributor.lastname == "Tamaki").first()) self.assertFalse(jtamaki_exists) jtamaki = Person(lastname="Tamaki", firstname="Jillian") author_illus = BookRecord(isbn="9781596437746", title="This One Summer", genre="Graphic Novel", author=[jtamaki], illustrator=[jtamaki], publisher="First Second", publish_year=2016) rv = self.client.post("/api/add/books", data=author_illus.request_data()) self.assertEquals(200, rv.status_code) jtamakis = (librarian.db.session.query(Contributor).filter( Contributor.firstname == "Jillian").filter( Contributor.lastname == "Tamaki").all()) self.assertEqual(1, len(jtamakis))
def __unpack_persons(self, person_list): if person_list: return frozenset([Person(**p) for p in person_list]) else: return None
def test_edit_book_contrib_correction(self): """ Another actual error encountered in testing. We are modifying "MIlo Manara" to "Milo Manara" but it would seem that get_or_create fetches "MIlo Manara" when given "Milo Manara". """ self.set_current_user(self.admin_user) # These two are always parallel arrays. contributor_objs = [ ContributorFactory(lastname="Manara", firstname="MIlo") ] illustrators = [co.make_plain_person() for co in contributor_objs] the_deleted = contributor_objs[-1] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Mumford and Sons", illustrator=illustrators, publish_year=2016, genre="Fiction") book_id = create_book(librarian.db.session, book, self.admin_user) librarian.db.session.commit() illustrator_role = Role.get_preset_role("Illustrator") book_illustrators = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == illustrator_role.id).filter( BookContribution.active).filter( Contributor.active).all()) illustrator_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_illustrators ]) self.assertEquals(set(illustrators), illustrator_persons) edited_book_illustrators = [ Person(lastname="McKean", firstname="Dave"), Person(lastname="Manara", firstname="Milo") ] edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, illustrator=edited_book_illustrators, publish_year=book.publish_year, genre=book.genre, id=book_id) librarian.db.session.commit() edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) updated_book_illustrators = (librarian.db.session.query( Contributor).filter(BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == illustrator_role.id).filter( BookContribution.active).filter( Contributor.active).all()) updated_illustrator_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in updated_book_illustrators ]) self.assertEqual(set(edited_book_illustrators), updated_illustrator_persons) # Verify that the BookRecord for the "deleted" contribution remains # but inactive. self.verify_inserted(BookContribution, book_id=book_id, contributor_id=the_deleted.id, role_id=illustrator_role.id, active=False) self.verify_inserted(Contributor, id=the_deleted.id, active=False)
def test_deepcopy(self): ronaldo = Person(firstname="Ronaldo", lastname="Nazario") cr7 = copy.deepcopy(ronaldo) self.assertFalse(cr7 is ronaldo)
def test_remove_duplicate_contributor_team(self): """ Yet another actual test case encountered live. For some reason, Preludes and Nocturnes was saved with the same Contributors for both Translators and Editors (note that Preludes and Nocturnes is not supposed to have Translators). Deleting all Translators does not seem to work. UPDATE: Looks like it was, indeed, a side-effect of the update code. When editing the Translators role, the Editors field is passed, creating the discrepancy. """ self.make_current_user() # These two are always parallel arrays. contributor_objs = [ContributorFactory() for _ in range(3)] editors = [co.make_plain_person() for co in contributor_objs] the_deleted = contributor_objs[-1] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Mumford and Sons", editor=editors, translator=editors, publish_year=2016, genre="Fiction") book_id = create_book(librarian.db.session, book, self.admin_user) librarian.db.session.commit() editor_role = Role.get_preset_role("Editor") translator_role = Role.get_preset_role("Translator") book_editors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == editor_role.id).filter( BookContribution.active).filter( Contributor.active).all()) book_translators = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == translator_role.id).filter( BookContribution.active).filter( Contributor.active).all()) editor_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_editors ]) self.assertEquals(set(editors), editor_persons) self.assertEquals(set(book_editors), set(book_translators)) # Delete all translators edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, editor=editors, publish_year=book.publish_year, genre=book.genre, id=book_id) edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) updated_book_editors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == editor_role.id).filter( BookContribution.active).filter( Contributor.active).all()) updated_editor_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in updated_book_editors ]) self.assertEqual(set(editor_persons), updated_editor_persons) updated_book_translators = ( librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == translator_role.id).filter( BookContribution.active).all()) self.assertEqual(0, len(updated_book_translators)) # Verify that the BookRecord for the "deleted" contribution remains # but inactive. for translator in book_translators: self.verify_inserted(BookContribution, book_id=book_id, contributor_id=translator.id, role_id=translator_role.id, active=False) self.verify_inserted(Contributor, id=translator.id, active=True)
def test_edit_book_contrib_correction(self): """ Actual (unexpected) error encountered while live testing. It would seem that the database might have race conditions where a pending book is uncommitted resulting to errors when pairing a Contributor with a role. """ self.set_current_user(self.admin_user) # These two are always parallel arrays. contributor_objs = [ ContributorFactory(lastname="Jill", firstname="Jack"), ContributorFactory(lastname="Stewart", firstname="John") ] authors = [co.make_plain_person() for co in contributor_objs] the_deleted = contributor_objs[-1] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Mumford and Sons", author=authors, publish_year=2016, genre="Fiction") book_id = create_book(librarian.db.session, book, self.admin_user) librarian.db.session.commit() js_autobio = BookRecord( isbn=fake.isbn(), title="JS Autobio", publisher="Green Cross", author=[Person(lastname="Stewart", firstname="Jon")], publish_year=2016, genre="Fiction") create_book(librarian.db.session, js_autobio, self.admin_user) # This is what makes this pass. librarian.db.session.commit() author_role = Role.get_preset_role("Author") book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_authors ]) self.assertEquals(set(authors), author_persons) edited_book_authors = [ Person(lastname="Jill", firstname="Jack"), Person(lastname="Stewart", firstname="Jon") ] edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, author=edited_book_authors, publish_year=book.publish_year, genre=book.genre, id=book_id) edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) updated_book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) updated_author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in updated_book_authors ]) self.assertEqual(set(edited_book_authors), updated_author_persons) # Verify that the BookRecord for the "deleted" contribution remains # but inactive. self.verify_inserted(BookContribution, book_id=book_id, contributor_id=the_deleted.id, role_id=author_role.id, active=False) self.verify_inserted(Contributor, id=the_deleted.id, active=False)
def test_edit_book_contrib_move(self): """ Test that moving contributors between roles produce the desired effect. """ self.make_current_user() # These two are always parallel arrays. contributor_objs = [ContributorFactory() for _ in range(3)] authors = [co.make_plain_person() for co in contributor_objs] the_deleted = contributor_objs[-1] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Mumford and Sons", author=authors, publish_year=2016, genre="Fiction") book_id = create_book(librarian.db.session, book, self.admin_user) librarian.db.session.commit() author_role = Role.get_preset_role("Author") book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_authors ]) self.assertEquals(set(authors), author_persons) # The last author is the one we delete edited_book_authors = authors[0:-1] edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, author=edited_book_authors, editor=[the_deleted.make_plain_person()], publish_year=book.publish_year, genre=book.genre, id=book_id) edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) updated_book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) updated_author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in updated_book_authors ]) self.assertEqual(set(edited_book_authors), updated_author_persons) # Verify that the BookRecord for the "deleted" contribution remains # but inactive. self.verify_inserted(BookContribution, book_id=book_id, contributor_id=the_deleted.id, role_id=author_role.id, active=False) the_deleted = librarian.db.session.query(Contributor).filter( Contributor.id == the_deleted.id).first() self.verify_inserted(Contributor, id=the_deleted.id, active=True)
def test_edit_book_contrib_delete_keepactive(self): """ Test deleting a contribution from a book where the contributor stays active from other books """ self.make_current_user() # These two are always parallel arrays. contributor_objs = [ContributorFactory() for _ in range(3)] authors = [co.make_plain_person() for co in contributor_objs] the_deleted = contributor_objs[-1] book = BookRecord(isbn=fake.isbn(), title=fake.title(), publisher="Mumford and Sons", author=authors, publish_year=2016, genre="Fiction") book_id = create_book(librarian.db.session, book, self.admin_user) # This will keep `the_deleted` alive. Get it? horcrux = BookRecord(isbn=fake.isbn(), title="Secrets of the Darkest Art", publisher="Scholastic", author=[the_deleted.make_plain_person()], publish_year=1967, genre="Black Magic") librarian.db.session.commit() create_book(librarian.db.session, horcrux, self.admin_user) librarian.db.session.commit() author_role = Role.get_preset_role("Author") book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in book_authors ]) self.assertEquals(set(authors), author_persons) # The last author is the one we delete edited_book_authors = authors[0:-1] edit_data = BookRecord(isbn=book.isbn, title=book.title, publisher=book.publisher, author=edited_book_authors, publish_year=book.publish_year, genre=book.genre, id=book_id) edit_book = self.client.post("/api/edit/books", data=edit_data.request_data()) self.assertEqual(200, edit_book.status_code) updated_book_authors = (librarian.db.session.query(Contributor).filter( BookContribution.book_id == book_id).filter( BookContribution.contributor_id == Contributor.id).filter( BookContribution.role_id == author_role.id).filter( BookContribution.active).filter( Contributor.active).all()) updated_author_persons = set([ Person(firstname=a.firstname, lastname=a.lastname) for a in updated_book_authors ]) self.assertEqual(set(edited_book_authors), updated_author_persons) # Verify that the BookRecord for the "deleted" contribution remains # but inactive. self.verify_inserted(BookContribution, book_id=book_id, contributor_id=the_deleted.id, role_id=author_role.id, active=False) # But the contributor remains active thanks to the horcrux! self.verify_inserted(Contributor, id=the_deleted.id, active=True)
def create_library( session, admin, roles, book_person_c=8, company_c=8, book_c=8, participant_c=8 ): """ Create a library in the database with the given counts. Returns a list of `BookRecord` objects. """ book_persons = [ContributorFactory(creator=admin) for _ in range(book_person_c)] printers = [BookCompanyFactory(creator=admin) for _ in range(company_c)] person_fns = [bp.firstname for bp in book_persons] for bp in book_persons: bp.creator_id = admin.id session.add(bp) for co in printers: co.creator_id = admin.id session.add(co) session.commit() printers = session.query(BookCompany).all() books = [BookFactory(publisher=random.choice(printers), creator=admin) for _ in range(book_c)] book_isbns = [b.isbn for b in books] for b in books: b.creator_id = admin.id session.add(b) session.commit() # Query books for their ids. Note that this bit assumes that the only books # in the DB right now are those just-created. books = session.query(Book).all() isbn_book_map = {book.isbn: book for book in books} library = {} # initialize the role fields for isbn in book_isbns: library[isbn] = { "title": isbn_book_map[isbn].title, "publisher": isbn_book_map[isbn].publisher.name, "genre": isbn_book_map[isbn].genre.name } for role in roles: library[isbn][role.name.lower()] = [] # Randomly assign persons to books as roles for _ in range(participant_c): rand_isbn = random.choice(book_isbns) rand_book = session.query(Book).filter(Book.isbn == rand_isbn).first() rand_person_fn = random.choice(person_fns) rand_person = session.query(Contributor).filter(Contributor.firstname == rand_person_fn).first() rand_role = random.choice(roles) _role = rand_role.name.lower() library[rand_isbn][_role].append(Person(lastname=rand_person.lastname, firstname=rand_person.firstname)) bp = BookContribution(book=rand_book, contributor=rand_person, role=rand_role, creator=admin) session.add(bp) session.flush() session.commit() library_list = [] for isbn in library.keys(): book = library[isbn] book["isbn"] = isbn book["id"] = isbn_book_map[isbn].id library_list.insert(0, BookRecord(**book)) return library_list
def make_person_object(): return Person(fuzzy_text.fuzz(), fuzzy_text.fuzz())
def edit_contrib(book, all_contribs, role, submitted_persons): """ Adds all new contributors to the session and deletes all removed contributors to the session. Where `submitted_persons` is the data straight out of the form (hence it is a JSON string), `all_contribs` are all the active contributions in the book as recorded in the DB (pre-edit). """ app.logger.debug("considering role %s" % role) parsons = json.loads(submitted_persons) form_records = set() # Create or load all the contributions mentioned in the form. for p in parsons: ce = contribution_exists(all_contribs, role.id, Person(**p)) if ce is not False: form_records.add(ce) else: contributor_record = get_or_create(Contributor, will_commit=False, firstname=p["firstname"], lastname=p["lastname"], creator=current_user) app.logger.debug("got contributor record %s" % contributor_record) app.logger.debug("will attach role %s" % role) if not contributor_record.active: contributor_record.active = True contribution = BookContribution(book=book, contributor=contributor_record, role=role, creator=current_user) db.session.add(contribution) form_records.add(contribution) recorded_contribs = set([ contrib for contrib in all_contribs if contrib.role.id == role.id ]) app.logger.debug("recorded contribs for %s %s" % (role, recorded_contribs)) app.logger.debug("form records %s" % form_records) deletables = recorded_contribs - form_records app.logger.debug("The deletables %s" % deletables) for d in deletables: d.active = False other_contrib = (BookContribution.query.filter( BookContribution.contributor_id == d.contributor_id).filter( or_(BookContribution.book_id != book.id, BookContribution.role_id != d.role_id)).filter( BookContribution.active).first()) app.logger.debug( "Contributor %s has another contribution %s (checked from %s)" % (d.contributor_id, other_contrib, role.name)) if other_contrib is None: app.logger.debug("Deactivating %s" % d) d.contributor.active = False
def make_plain_person(self): return Person(lastname=self.lastname, firstname=self.firstname)