from django.test import TestCase
import json

from django.test import TestCase, Client

from BookStore import error, function
from store.models import Store, Book, Tag
from user.models import User, Address


class GlobalBookTest(TestCase):
    def setUp(self) -> None:
        data = {
            'user_id': 'yzm',
            'password': 'aaaaaa'
        }
        buyer = User.objects.create(username=data['user_id'], password=data['password'], balance=10000000)
        seller = User.objects.create(username='stm', password='aaaaaa', balance=0.01)
        store = Store.objects.create(storeName='648全球连锁店', owner=seller, address='648')
        book = Book.objects.create(bookID='book_id_1', stock=10, store=store, isbn='1', title='book', price='100.00',
                                   author='yzm', content='chapter1', bookIntro='good')
        Tag.objects.create(tag='good', book=book)
        self.client = Client(HTTP_TOKEN=function.generate_token({'user_id': 'yzm', 'terminal': '127.0.0.1'}))

    def test_global_book_fail(self):
        data = {
            'key': 'title',
            'q': 'book_1',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {
            'message': message,
            'books': [],
            'num': 0,
            'page_num': 1
        }
        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_book_page_not_correct(self):
        data = {
            'key': 'title',
            'q': 'book',
            'sort': 'hot',
            'page': -1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'message': 'ok',
                  'num': 1,
                  'page_num': 1}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_book_page_title_success(self):
        data = {
            'key': 'title',
            'q': 'book',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'message': 'ok',
                  'num': 1,
                  'page_num': 1}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_book_page_author_success(self):
        data = {
            'key': 'author',
            'q': 'yzm',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'message': 'ok',
                  'num': 1,
                  'page_num': 1}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_book_page_content_success(self):
        data = {
            'key': 'content',
            'q': 'chapter1',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'message': 'ok',
                  'num': 1,
                  'page_num': 1}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_book_page_tag_success(self):
        data = {
            'key': 'tag',
            'q': 'good',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'message': 'ok',
                  'num': 1,
                  'page_num': 1}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_book_page_book_info_success(self):
        data = {
            'key': 'book_intro',
            'q': 'good',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'message': 'ok',
                  'num': 1,
                  'page_num': 1}

        self.assertJSONEqual(response.content, expected_data=expect)


class GlobalStoreTest(TestCase):
    def setUp(self) -> None:
        data = {
            'user_id': 'yzm',
            'password': 'aaaaaa'
        }
        buyer = User.objects.create(username=data['user_id'], password=data['password'], balance=10000000)
        seller = User.objects.create(username='stm', password='aaaaaa', balance=0.01)
        store = Store.objects.create(storeName='648全球连锁店', owner=seller, address='648')
        book = Book.objects.create(bookID='book_id_1', stock=10, store=store, isbn='1', title='book', price='100.00',
                                   author='yzm', content='chapter1', bookIntro='good')
        Tag.objects.create(tag='good', book=book)
        self.client = Client(HTTP_TOKEN=function.generate_token({'user_id': 'yzm', 'terminal': '127.0.0.1'}))

    def test_global_store_page_store_id_success(self):
        data = {
            'key': 'store_id',
            'q': '648全球连锁店',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_store/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'message': 'ok',
                  'num': 1,
                  'page_num': 1,
                  'stores': [{'address': '648',
                              'create_date': '2021-12-16',
                              'info': '',
                              'sold': 0,
                              'store_id': '648全球连锁店'}]
                  }

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_store_page_address_success(self):
        data = {
            'key': 'address',
            'q': '648',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_store/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'message': 'ok',
                  'num': 1,
                  'page_num': 1,
                  'stores': [{'address': '648',
                              'create_date': '2021-12-16',
                              'info': '',
                              'sold': 0,
                              'store_id': '648全球连锁店'}]
                  }

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_store_page_not_correct(self):
        data = {
            'key': 'address',
            'q': '648',
            'sort': 'hot',
            'page': -1
        }
        response = self.client.get('/search/global_store/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'message': 'ok',
                  'num': 1,
                  'page_num': 1,
                  'stores': [{'address': '648',
                              'create_date': '2021-12-16',
                              'info': '',
                              'sold': 0,
                              'store_id': '648全球连锁店'}]
                  }

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_global_store_fail(self):
        data = {
            'key': 'store_id',
            'q': '648环球港',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/global_store/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'message': 'ok',
                  'num': 0,
                  'page_num': 1,
                  'stores': []
                  }

        self.assertJSONEqual(response.content, expected_data=expect)


class StoreBookTest(TestCase):
    def setUp(self) -> None:
        data = {
            'user_id': 'yzm',
            'password': 'aaaaaa'
        }
        buyer = User.objects.create(username=data['user_id'], password=data['password'], balance=10000000)
        seller = User.objects.create(username='stm', password='aaaaaa', balance=0.01)
        store = Store.objects.create(storeName='648全球连锁店', owner=seller, address='648')
        book = Book.objects.create(bookID='book_id_1', stock=10, store=store, isbn='1', title='book', price='100.00',
                                   author='yzm', content='chapter1', bookIntro='good')
        Tag.objects.create(tag='good', book=book)
        self.client = Client(HTTP_TOKEN=function.generate_token({'user_id': 'yzm', 'terminal': '127.0.0.1'}))

    def test_store_book_no_params(self):
        data = {
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = error.invalid_parameter()
        self.assertEqual(response.status_code, code)
        expect = {
            'message': message
        }
        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_store_not_exist(self):
        data = {
            'store_id': "648环球港",
            'key': 'title',
            'q': 'book',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = error.store_id_doesnt_exist(data["store_id"])
        self.assertEqual(response.status_code, code)
        expect = {
            'message': message
        }
        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_fail(self):
        data = {
            'store_id': "648全球连锁店",
            'key': 'title',
            'q': 'book_1',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 0,
                  'books': [],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_page_not_correct(self):
        data = {
            'store_id': "648全球连锁店",
            'key': 'title',
            'q': 'book',
            'sort': 'hot',
            'page': -1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 1,
                  'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_page_title_success(self):
        data = {
            'store_id': "648全球连锁店",
            'key': 'title',
            'q': 'book',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 1,
                  'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_page_author_success(self):
        data = {
            'store_id': "648全球连锁店",
            'key': 'author',
            'q': 'yzm',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 1,
                  'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_page_content_success(self):
        data = {
            'store_id': '648全球连锁店',
            'key': 'content',
            'q': 'chapter1',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 1,
                  'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_page_tag_success(self):
        data = {
            'store_id': '648全球连锁店',
            'key': 'tag',
            'q': 'good',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 1,
                  'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)

    def test_store_book_page_book_info_success(self):
        data = {
            'store_id': '648全球连锁店',
            'key': 'book_intro',
            'q': 'good',
            'sort': 'hot',
            'page': 1
        }
        response = self.client.get('/search/store_book/', data=data, content_type='application/json')
        code, message = 200, 'ok'
        self.assertEqual(response.status_code, code)
        expect = {'book_num': 1,
                  'books': [{'author': 'yzm',
                             'book_id': 'book_id_1',
                             'off': False,
                             'price': '100.00',
                             'pub_year': None,
                             'sold': 0,
                             'stock_level': 10,
                             'store_id': '648全球连锁店',
                             'title': 'book'}],
                  'books_page': 1,
                  'books_page_num': 1,
                  'message': 'ok'}

        self.assertJSONEqual(response.content, expected_data=expect)
