def create_movie(payload):
    try:
        data = json.loads(request.data)
        name = data.get('title', None)
        release_date = data.get('release_date', None)
        actor_ids = data.get('actors', [])

        if (name is None) or (len(name.strip()) == 0):
            abort(400, 'Movie name is not specified.')

        if ((isinstance(release_date, int) is False) or
                (isValidDateTimeInSeconds(release_date) is False)):
            abort(400, 'Invalid release date')

        actors = Actor.query.filter(Actor.id.in_(actor_ids)).all()

        movie = Movie(title=name, release_date=release_date)
        movie.performing_actors = actors

        movie.insert()

        return jsonify(movie.serialize_with_actors())

    except Exception as error:
        print(sys.exc_info())
        raise error
def add_movie(payload):

    data = request.get_json()

    if not ('title' in data):
        abort(404)

    title = data.get('title', None)
    new_movie_genrs = data.get('movie_genrs', None)
    new_release_date = data.get('release_date', None)

    # i want body to have title, release_date, and movie_genrs

    try:
        new_movie = Movie(title=title,
                          release_date=new_release_date,
                          movie_genrs=new_movie_genrs)
        new_movie.insert()

        return jsonify({'success': True, 'added': [new_movie.get_movie()]})

    except Exception:
        abort(422)
def create_movie(_):
    from backend.models import Movie
    req_data = request.get_json()
    movie = Movie.insert(**req_data)
    return build_orm_json(movie, fail_err_msg='Not able to insert new actor')
class MoviesApiTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()
        self.mock_actor = Actor(name="Test Actor", age=50, gender='M')
        self.mock_movie = Movie(title="Test Movie",
                                release_date=1597277251,
                                performing_actors=[self.mock_actor])

    def tearDown(self):
        super().tearDown()

    def test_get_all_movies_empty_database(self):
        response = self.client.get(
            '/api/movies',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 0)

    def test_get_all_movies_with_records(self):
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.get(
            '/api/movies',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 1)
        self.assertEqual(len(data['results']), 1)

    def test_get_all_movies_rbac_check(self):
        self.mock_movie.insert()

        response = self.client.get('/api/movies')
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(data['success'], False)

        response = self.client.get(
            '/api/movies',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 1)

        response = self.client.get(
            '/api/movies',
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 1)

        response = self.client.get(
            '/api/movies',
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 1)

    """ Verify GET /api/movies/<movie_id> endpoint """

    def test_get_movie_by_id_empty_database(self):
        response = self.client.get(
            '/api/movies/0',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 404)
        self.assertEqual(data['success'], False)

    def test_get_movie_by_id(self):
        """ Insert records first """
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.get(
            f'/api/movies/{self.mock_movie.id}',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data["id"], self.mock_movie.id)
        self.assertEqual(data["title"], self.mock_movie.title)

    """ Verify POST /api/movies endpoint """

    def test_create_movies_invalid_payload(self):
        payload = {"release_date": round(datetime.now().timestamp())}

        response = self.client.post(
            '/api/movies',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 400)
        self.assertFalse(data['success'])

    def test_create_movies_valid_payload(self):
        payload = self.mock_movie.serialize()

        response = self.client.post(
            '/api/movies',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])
        self.assertEqual(data["title"], self.mock_movie.title)

    def test_create_movies_rbac_check(self):
        payload = self.mock_movie.serialize()

        response = self.client.post(
            '/api/movies',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.post(
            '/api/movies',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.post(
            '/api/movies',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

    """ Verify PATCH /api/movies/<movie_id> endpoint """

    def test_edit_movie_invalid_movie_id(self):
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.patch(
            '/api/movies/99999',
            json={},
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 404)
        self.assertFalse(data['success'])

    def test_edit_movie_valid_payload(self):
        self.mock_movie.insert()

        payload = {"title": "Updated Movie Title"}

        response = self.client.patch(
            f'/api/movies/{self.mock_movie.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])
        self.assertEqual(data["title"], payload["title"])

    def test_edit_movie_rbac_check(self):
        self.mock_movie.insert()
        payload = {
            "title": "Update Movie Title",
            "age": round(datetime.now().timestamp())
        }

        response = self.client.patch(
            f'/api/movies/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.patch(
            f'/api/movies/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

        response = self.client.patch(
            f'/api/movies/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

    """ Verify DELETE /api/movies/<movie_id> endpoint """

    def test_delete_movie_invalid_movie_id(self):
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.delete(
            '/api/movies/99999',
            json={},
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data['success'])

    def test_delete_movie_valid_id(self):
        self.mock_movie.insert()

        response = self.client.delete(
            f'/api/movies/{self.mock_movie.id}',
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["success"])

    def test_delete_movie_rbac_check(self):
        self.mock_movie.insert()

        response = self.client.delete(
            f'/api/movies/{self.mock_movie.id}',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.delete(
            f'/api/movies/{self.mock_movie.id}',
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.delete(
            f'/api/movies/{self.mock_movie.id}',
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["success"])
class ActorsApiTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()
        self.mock_actor = Actor(name="Test Actor", age=50, gender='M')
        self.mock_movie = Movie(title="Test Movie",
                                release_date=1597277251,
                                performing_actors=[self.mock_actor])

    def tearDown(self):
        super().tearDown()

    def test_get_index_page(self):
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, "text/html")

    """ Verify GET /api/actors endpoint """

    def test_get_all_actors_wihtout_token(self):
        response = self.client.get('/api/actors')
        data = json.loads(response.data)

        self.assertEqual(response.status_code, 401)
        self.assertEqual(data['success'], False)

    def test_get_all_actors_empty_database(self):
        response = self.client.get(
            '/api/actors',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 0)
        self.assertEqual(len(data['results']), 0)

    def test_get_all_actors_returns_actors(self):
        self.mock_actor.insert()
        self.mock_movie.insert()
        response = self.client.get(
            '/api/actors',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(data['count'], 1)
        self.assertEqual(len(data['results']), 1)

    def test_get_all_actors_rbac_check(self):
        response = self.client.get('/api/actors')
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(data['success'], False)

        response = self.client.get(
            '/api/actors',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)

        response = self.client.get(
            '/api/actors',
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)

        response = self.client.get(
            '/api/actors',
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)

    """ Verify GET /api/actors/<actor_id> endpoint """

    def test_get_actor_by_id_empty_database(self):
        response = self.client.get(
            '/api/actors/0',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 404)
        self.assertEqual(data['success'], False)

    def test_get_actor_by_id(self):
        """ Insert records first """
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.get(
            f'/api/actors/{self.mock_actor.id}',
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(data["id"], self.mock_actor.id)
        self.assertEqual(data["name"], self.mock_actor.name)

    """ Verify POST /api/actors endpoint """

    def test_create_actor_invalid_payload(self):
        payload = {"name": "", "age": 0, "gender": "U"}

        response = self.client.post(
            '/api/actors',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 400)
        self.assertFalse(data['success'])

    def test_create_actor_valid_payload(self):
        payload = self.mock_actor.serialize()

        response = self.client.post(
            '/api/actors',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])
        self.assertEqual(data["name"], self.mock_actor.name)

    def test_create_actor_rbac_check(self):
        payload = self.mock_actor.serialize()

        response = self.client.post(
            '/api/actors',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.post(
            '/api/actors',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

        response = self.client.post(
            '/api/actors',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

    """ Verify PATCH /api/actors/<actor_id> endpoint """

    def test_edit_actor_invalid_actor_id(self):
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.patch(
            '/api/actors/99999',
            json={},
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 404)
        self.assertFalse(data['success'])

    def test_edit_actor_valid_payload(self):
        self.mock_actor.insert()

        payload = {"name": "Updated Actor Name"}

        response = self.client.patch(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])
        self.assertEqual(data["name"], payload["name"])

    def test_edit_actor_rbac_check(self):
        self.mock_actor.insert()
        payload = {"name": "Update Actor Name", "age": 99}

        response = self.client.patch(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.patch(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

        response = self.client.patch(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["id"])

    """ Verify DELETE /api/actors/<actor_id> endpoint """

    def test_delete_actor_invalid_actor_id(self):
        self.mock_actor.insert()
        self.mock_movie.insert()

        response = self.client.delete(
            '/api/actors/99999',
            json={},
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data['success'])

    def test_delete_actor_valid_id(self):
        self.mock_actor.insert()

        response = self.client.delete(
            f'/api/actors/{self.mock_actor.id}',
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["success"])

    def test_delete_actor_rbac_check(self):
        self.mock_actor.insert()
        payload = {"name": "Update Actor Name", "age": 99}

        response = self.client.delete(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.assistant_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 403)
        self.assertFalse(data["success"])

        response = self.client.delete(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.director_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["success"])

        response = self.client.delete(
            f'/api/actors/{self.mock_actor.id}',
            json=payload,
            headers={'Authorization': f'Bearer {tokens.producer_jwt_token}'})
        data = json.loads(response.data)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(data["success"])