def test_save_book(monkeypatch, setup_mdb_dir, caplog):
    tmpdir = setup_mdb_dir
    os.chdir(tmpdir)
    mdb_file = os.path.join(TESTS_DIR, 'all_test_files', 'manga_db.sqlite.sql')
    memdb = load_db_from_sql_file(mdb_file, ':memory:', True)
    monkeypatch.setattr('manga_db.manga_db.MangaDB._load_or_create_sql_db', (lambda x, y, z: (memdb, None)))
    mdb = MangaDB(tmpdir, mdb_file)
    db_con = memdb
    ei_data = dict(id=None, book_id=None, url='http://test1.com', id_onpage='1111', imported_from=1, upload_date=datetime.date(2018, 4, 13), uploader='Uploader', censor_id=1, rating=4.19, ratings=165, favorites=300, downloaded=None, last_update=None, outdated=None)
    b1_data = dict(id=None, title_eng='Add1', title_foreign='Foreign1', language_id=1, pages=25, chapter_status='Vol. 2 Ch. 14', read_status=13, status_id=1, my_rating=None, category=['Manga'], collection=None, groups=['Artistgroup'], artist=['Diff1', 'Diff2'], parody=['Blabla'], character=['Char1', 'Char2', 'Char3'], list=['to-read', 'to-download'], tag=['Tag1', 'Tag2', 'Tag3'], ext_infos=None, last_change=datetime.date(2018, 6, 3), note=None, favorite=None, cover_timestamp=None, nsfw=1)
    b1 = Book(mdb, **b1_data)
    b1_data['cover_timestamp'] = 0.0
    ei1 = ExternalInfo(mdb, b1, **ei_data)
    ei2 = ExternalInfo(mdb, b1, **ei_data)
    ei2.id_onpage = '43506'
    b1.ext_infos = [ei1, ei2]
    assert (b1._in_db is False)
    (bid, outdated) = b1.save()
    assert (bid == 18)
    assert (b1.id == 18)
    assert (b1._in_db is True)
    assert (mdb.id_map[b1.key] is b1)
    assert (not b1._committed_state)
    book_info_db = all_book_info(db_con, 18, include_id=True)
    assert (len(book_info_db) == 2)
    assert (book_info_db[0]['favorite'] == 0)
    assert (b1.favorite == 0)
    compare_cols_row_book_data(b1, book_info_db[0], b1_data, special={'favorite': 0})
    assert (outdated == [20])
    eis = db_con.execute('SELECT id, book_id, id_onpage FROM ExternalInfo WHERE id > 18').fetchall()
    assert (len(eis) == 2)
    assert (eis[0]['book_id'] == 18)
    assert (eis[1]['book_id'] == 18)
    assert (eis[0]['id_onpage'] == '1111')
    assert (eis[1]['id_onpage'] == '43506')
    b2 = Book(mdb, title_eng='Test2', favorite=1, pages=11, status_id=1, nsfw=0)
    b2.language = 'Krababbl'
    (bid, _) = b2.save()
    assert (bid == 19)
    assert (b2.id == 19)
    expected_lang_id = ((len(LANG_IDS) / 2) + 1)
    assert (b2.language_id == expected_lang_id)
    lang = db_con.execute("SELECT id FROM Languages WHERE name = 'Krababbl'").fetchall()
    assert lang
    assert (lang[0][0] == expected_lang_id)
    brow = db_con.execute('SELECT title_eng, favorite FROM Books WHERE id = 19').fetchone()
    assert (brow[0] == 'Test2')
    assert (brow['favorite'] == 1)
    assert (b2.favorite == 1)
    assert (b2._in_db is True)
    assert (not b2._committed_state)
    assert (mdb.id_map[b2.key] is b2)
    bu1 = Book(mdb, id=None, title_eng='Kangofu-san ni Kintama Sakusei Saremashita', title_foreign='看護婦さんにキンタマ搾精されました', in_db=False)
    bu1.in_db = True
    caplog.clear()
    assert (bu1.save(block_update=True) == (None, None))
    assert (caplog.record_tuples == [('manga_db.manga', logging.DEBUG, f'Book was found in DB(id 15) but saving was blocked due to block_update option!')])
    bu2 = mdb.get_book(11)
    caplog.clear()
    assert (not bu2._committed_state)
    assert (bu2.save() == (11, None))
    assert (caplog.record_tuples == [('manga_db.manga', logging.DEBUG, 'No changes to save for book with id 11')])
    assert (not bu2._committed_state)
    before = bu2.export_for_db()
    before.update({col: (getattr(bu2, col) if getattr(bu2, col) else None) for col in bu2.ASSOCIATED_COLUMNS})
    bu2.language = 'adlalad'
    change = {'title_eng': 'Altered', 'language_id': 3, 'my_rating': 4.75, 'favorite': 1, 'tag': 'Large Breasts;Test33;Nakadashi;Ahegao;Gender Bender;Dark Skin;Elf;Body Swap;Bondage;Filming;Test Tag'.split(';'), 'artist': ['Taniguchi-san', 'Newartist'], 'category': ['Manga'], 'character': ['Char111', 'Char222']}
    bu2.update_from_dict(change)
    before.update(change)
    (bid, _) = bu2.save()
    book_info_db = all_book_info(db_con, 11, include_id=True)
    compare_cols_row_book_data(bu2, book_info_db, before, special={'last_change': datetime.date.today()})
    assert (not bu2._committed_state)
    assert (bu2.last_change == datetime.date.today())
    assert (book_info_db['last_change'] == datetime.date.today())
    bu3 = mdb.get_book(7)
    assert (not bu3._committed_state)
    before = bu3.export_for_db()
    before.update({col: (getattr(bu3, col) if getattr(bu3, col) else None) for col in bu3.ASSOCIATED_COLUMNS})
    change = {'title_foreign': 'ForeignAltered', 'pages': 13, 'note': 'Note blabla', 'tag': None, 'artist': None, 'category': ['Manga'], 'collection': ['Col1', 'Col2'], 'groups': ['Grp1', 'Grp2', 'Senpenbankashiki']}
    bu3.update_from_dict(change)
    before.update(change)
    (bid, _) = bu3.save()
    book_info_db = all_book_info(db_con, 7, include_id=True)
    compare_cols_row_book_data(bu3, book_info_db, before, special={'last_change': datetime.date.today()})
    assert (not bu3._committed_state)
    assert (bu3.last_change == datetime.date.today())
    assert (book_info_db['last_change'] == datetime.date.today())
def test_save_book(monkeypatch, setup_mdb_dir, caplog):
    tmpdir = setup_mdb_dir
    os.chdir(tmpdir)
    mdb_file = os.path.join(TESTS_DIR, 'all_test_files', 'manga_db.sqlite.sql')
    memdb = load_db_from_sql_file(mdb_file, ':memory:', True)
    monkeypatch.setattr('manga_db.manga_db.MangaDB._load_or_create_sql_db', (lambda x, y, z: (memdb, None)))
    mdb = MangaDB(tmpdir, mdb_file)
    db_con = memdb
    ei_data = dict(id=None, book_id=None, url='http://test1.com', id_onpage='1111', imported_from=1, upload_date=datetime.date(2018, 4, 13), uploader='Uploader', censor_id=1, rating=4.19, ratings=165, favorites=300, downloaded=None, last_update=None, outdated=None)
    b1_data = dict(id=None, title_eng='Add1', title_foreign='Foreign1', language_id=1, pages=25, chapter_status='Vol. 2 Ch. 14', read_status=13, status_id=1, my_rating=None, category=['Manga'], collection=None, groups=['Artistgroup'], artist=['Diff1', 'Diff2'], parody=['Blabla'], character=['Char1', 'Char2', 'Char3'], list=['to-read', 'to-download'], tag=['Tag1', 'Tag2', 'Tag3'], ext_infos=None, last_change=datetime.date(2018, 6, 3), note=None, favorite=None, cover_timestamp=None, nsfw=1)
    b1 = Book(mdb, **b1_data)
    b1_data['cover_timestamp'] = 0.0
    ei1 = ExternalInfo(mdb, b1, **ei_data)
    ei2 = ExternalInfo(mdb, b1, **ei_data)
    ei2.id_onpage = '43506'
    b1.ext_infos = [ei1, ei2]
    assert (b1._in_db is False)
    (bid, outdated) = b1.save()
    assert (bid == 18)
    assert (b1.id == 18)
    assert (b1._in_db is True)
    assert (mdb.id_map[b1.key] is b1)
    assert (not b1._committed_state)
    book_info_db = all_book_info(db_con, 18, include_id=True)
    assert (len(book_info_db) == 2)
    assert (book_info_db[0]['favorite'] == 0)
    assert (b1.favorite == 0)
    compare_cols_row_book_data(b1, book_info_db[0], b1_data, special={'favorite': 0})
    assert (outdated == [20])
    eis = db_con.execute('SELECT id, book_id, id_onpage FROM ExternalInfo WHERE id > 18').fetchall()
    assert (len(eis) == 2)
    assert (eis[0]['book_id'] == 18)
    assert (eis[1]['book_id'] == 18)
    assert (eis[0]['id_onpage'] == '1111')
    assert (eis[1]['id_onpage'] == '43506')
    b2 = Book(mdb, title_eng='Test2', favorite=1, pages=11, status_id=1, nsfw=0)
    b2.language = 'Krababbl'
    (bid, _) = b2.save()
    assert (bid == 19)
    assert (b2.id == 19)
    expected_lang_id = ((len(LANG_IDS) / 2) + 1)
    assert (b2.language_id == expected_lang_id)
    lang = db_con.execute("SELECT id FROM Languages WHERE name = 'Krababbl'").fetchall()
    assert lang
    assert (lang[0][0] == expected_lang_id)
    brow = db_con.execute('SELECT title_eng, favorite FROM Books WHERE id = 19').fetchone()
    assert (brow[0] == 'Test2')
    assert (brow['favorite'] == 1)
    assert (b2.favorite == 1)
    assert (b2._in_db is True)
    assert (not b2._committed_state)
    assert (mdb.id_map[b2.key] is b2)
    bu1 = Book(mdb, id=None, title_eng='Kangofu-san ni Kintama Sakusei Saremashita', title_foreign='看護婦さんにキンタマ搾精されました', in_db=False)
    bu1.in_db = True
    caplog.clear()
    assert (bu1.save(block_update=True) == (None, None))
    assert (caplog.record_tuples == [('manga_db.manga', logging.DEBUG, f'Book was found in DB(id 15) but saving was blocked due to block_update option!')])
    bu2 = mdb.get_book(11)
    caplog.clear()
    assert (not bu2._committed_state)
    assert (bu2.save() == (11, None))
    assert (caplog.record_tuples == [('manga_db.manga', logging.DEBUG, 'No changes to save for book with id 11')])
    assert (not bu2._committed_state)
    before = bu2.export_for_db()
    before.update({col: (getattr(bu2, col) if getattr(bu2, col) else None) for col in bu2.ASSOCIATED_COLUMNS})
    bu2.language = 'adlalad'
    change = {'title_eng': 'Altered', 'language_id': 3, 'my_rating': 4.75, 'favorite': 1, 'tag': 'Large Breasts;Test33;Nakadashi;Ahegao;Gender Bender;Dark Skin;Elf;Body Swap;Bondage;Filming;Test Tag'.split(';'), 'artist': ['Taniguchi-san', 'Newartist'], 'category': ['Manga'], 'character': ['Char111', 'Char222']}
    bu2.update_from_dict(change)
    before.update(change)
    (bid, _) = bu2.save()
    book_info_db = all_book_info(db_con, 11, include_id=True)
    compare_cols_row_book_data(bu2, book_info_db, before, special={'last_change': datetime.date.today()})
    assert (not bu2._committed_state)
    assert (bu2.last_change == datetime.date.today())
    assert (book_info_db['last_change'] == datetime.date.today())
    bu3 = mdb.get_book(7)
    assert (not bu3._committed_state)
    before = bu3.export_for_db()
    before.update({col: (getattr(bu3, col) if getattr(bu3, col) else None) for col in bu3.ASSOCIATED_COLUMNS})
    change = {'title_foreign': 'ForeignAltered', 'pages': 13, 'note': 'Note blabla', 'tag': None, 'artist': None, 'category': ['Manga'], 'collection': ['Col1', 'Col2'], 'groups': ['Grp1', 'Grp2', 'Senpenbankashiki']}
    bu3.update_from_dict(change)
    before.update(change)
    (bid, _) = bu3.save()
    book_info_db = all_book_info(db_con, 7, include_id=True)
    compare_cols_row_book_data(bu3, book_info_db, before, special={'last_change': datetime.date.today()})
    assert (not bu3._committed_state)
    assert (bu3.last_change == datetime.date.today())
    assert (book_info_db['last_change'] == datetime.date.today())