Exemple #1
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)
        self.file = api_utils.create_test_file(self.node, self.user)

    def test_must_have_auth(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           auth=user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_get_file(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        attributes = res.json['data']['attributes']
        assert_equal(attributes['path'], self.file.path)
        assert_equal(attributes['kind'], self.file.kind)
        assert_equal(attributes['name'], self.file.name)
        assert_equal(attributes['materialized_path'],
                     self.file.materialized_path)
        assert_equal(attributes['last_touched'], None)
        assert_equal(attributes['provider'], self.file.provider)
        assert_equal(attributes['size'], self.file.versions[-1].size)
        assert_equal(
            attributes['date_modified'],
            _dt_to_iso8601(
                self.file.versions[-1].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(
            attributes['date_created'],
            _dt_to_iso8601(
                self.file.versions[0].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['extra']['hashes']['md5'], None)
        assert_equal(attributes['extra']['hashes']['sha256'], None)

    def test_file_has_comments_link(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(
            API_BASE, self.node._id,
            self.file.get_guid()._id)
        url = res.json['data']['relationships']['comments']['links'][
            'related']['href']
        assert_in(expected_url, url)

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node,
                                 target=self.file.get_guid(),
                                 user=contributor,
                                 page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(
            API_BASE, self.file._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments'][
            'links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth)
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           auth=self.user.auth)
        assert_equal(
            self.user._id, res.json['data']['relationships']['checkout']
            ['links']['related']['meta']['id'])
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id), res.json['data']
            ['relationships']['checkout']['links']['related']['href'])

        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
                                    auth=self.user.auth)
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'type': 'Wrong type.',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': '12345',
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE,
            self.file._id), {'data': {
                'id': self.file._id,
                'type': 'files'
            }},
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': user._id
                    }
                }
            },
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_admin_can_checkout(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)
Exemple #2
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user, comment_level="public")
        self.file = api_utils.create_test_file(self.node, self.user, create_guid=False)
        self.file_url = "/{}files/{}/".format(API_BASE, self.file._id)

    def test_must_have_auth(self):
        res = self.app.get(self.file_url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get(self.file_url, auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_unvisited_file_has_no_guid(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json["data"]["attributes"]["guid"], None)

    def test_visited_file_has_guid(self):
        guid = self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_is_not_none(guid)
        assert_equal(res.json["data"]["attributes"]["guid"], guid._id)

    @mock.patch("api.base.throttling.CreateGuidThrottle.allow_request")
    def test_file_guid_not_created_with_basic_auth(self, mock_allow):
        res = self.app.get(self.file_url + "?create_guid=1", auth=self.user.auth)
        guid = res.json["data"]["attributes"].get("guid", None)
        assert_equal(res.status_code, 200)
        assert_equal(mock_allow.call_count, 1)
        assert guid is None

    @mock.patch("api.base.throttling.CreateGuidThrottle.allow_request")
    def test_file_guid_created_with_cookie(self, mock_allow):
        session = Session(data={"auth_user_id": self.user._id})
        session.save()
        cookie = itsdangerous.Signer(website_settings.SECRET_KEY).sign(session._id)
        self.app.set_cookie(website_settings.COOKIE_NAME, str(cookie))

        res = self.app.get(self.file_url + "?create_guid=1", auth=self.user.auth)

        self.app.reset()  # clear cookie

        assert_equal(res.status_code, 200)

        guid = res.json["data"]["attributes"].get("guid", None)
        assert_is_not_none(guid)

        assert_equal(guid, self.file.get_guid()._id)
        assert_equal(mock_allow.call_count, 1)

    def test_get_file(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ["data"])
        attributes = res.json["data"]["attributes"]
        assert_equal(attributes["path"], self.file.path)
        assert_equal(attributes["kind"], self.file.kind)
        assert_equal(attributes["name"], self.file.name)
        assert_equal(attributes["materialized_path"], self.file.materialized_path)
        assert_equal(attributes["last_touched"], None)
        assert_equal(attributes["provider"], self.file.provider)
        assert_equal(attributes["size"], self.file.versions[-1].size)
        assert_equal(attributes["current_version"], len(self.file.history))
        assert_equal(
            attributes["date_modified"], _dt_to_iso8601(self.file.versions[-1].date_created.replace(tzinfo=pytz.utc))
        )
        assert_equal(
            attributes["date_created"], _dt_to_iso8601(self.file.versions[0].date_created.replace(tzinfo=pytz.utc))
        )
        assert_equal(attributes["extra"]["hashes"]["md5"], None)
        assert_equal(attributes["extra"]["hashes"]["sha256"], None)
        assert_equal(attributes["tags"], [])

    def test_file_has_rel_link_to_owning_project(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in("node", res.json["data"]["relationships"].keys())
        expected_url = self.node.api_v2_url
        actual_url = res.json["data"]["relationships"]["node"]["links"]["related"]["href"]
        assert_in(expected_url, actual_url)

    def test_file_has_comments_link(self):
        self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in("comments", res.json["data"]["relationships"].keys())
        url = res.json["data"]["relationships"]["comments"]["links"]["related"]["href"]
        assert_equal(self.app.get(url, auth=self.user.auth).status_code, 200)
        assert_equal(res.json["data"]["type"], "files")

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node, target=self.file.get_guid(create=True), user=contributor, page="files")
        res = self.app.get("/{}files/{}/?related_counts=True".format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json["data"]["relationships"]["comments"]["links"]["related"]["meta"]["unread"]
        assert_equal(unread_comments, 1)

    def test_only_project_contrib_can_comment_on_closed_project(self):
        self.node.comment_level = "private"
        self.node.is_public = True
        self.node.save()

        res = self.app.get(self.file_url, auth=self.user.auth)
        can_comment = res.json["data"]["attributes"]["current_user_can_comment"]
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json["data"]["attributes"]["current_user_can_comment"]
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_any_loggedin_user_can_comment_on_open_project(self):
        self.node.is_public = True
        self.node.save()
        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json["data"]["attributes"]["current_user_can_comment"]
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

    def test_non_logged_in_user_cant_comment(self):
        self.node.is_public = True
        self.node.save()
        res = self.app.get(self.file_url)
        can_comment = res.json["data"]["attributes"]["current_user_can_comment"]
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
        )
        self.file.reload()
        self.file.save()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(len(self.node.logs), 2)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)
        assert_equal(self.user._id, res.json["data"]["relationships"]["checkout"]["links"]["related"]["meta"]["id"])
        assert_in(
            "/{}users/{}/".format(API_BASE, self.user._id),
            res.json["data"]["relationships"]["checkout"]["links"]["related"]["href"],
        )

        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": None}}},
            auth=self.user.auth,
        )
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"type": "files", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "Wrong type.", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": "12345", "type": "files", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            self.file_url, {"data": {"id": self.file._id, "type": "files"}}, auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_IN)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_admin_can_checkout(self):
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_cannot_checkin_when_already_checked_in(self):
        count = len(self.node.logs)
        assert_false(self.file.is_checked_out)
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(len(self.node.logs), count)
        assert_equal(self.file.checkout, None)

    def test_cannot_checkout_when_checked_out(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        count = len(self.node.logs)
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, user)
        assert_equal(len(self.node.logs), count)

    def test_noncontrib_cannot_checkout(self):
        user = AuthUserFactory()
        assert_equal(self.file.checkout, None)
        assert user._id not in self.node.permissions.keys()
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": self.user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_read_contrib_cannot_checkout(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=["read"])
        self.node.save()
        assert_false(self.node.can_edit(user=user))
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": None}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=["read", "write"])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": None}}},
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_removed_contrib_files_checked_in(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=["read", "write"])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        assert_true(self.file.is_checked_out)
        with capture_signals() as mock_signals:
            self.node.remove_contributor(user, auth=Auth(user))
        assert_equal(mock_signals.signals_sent(), set([contributor_removed]))
        self.file.reload()
        assert_false(self.file.is_checked_out)

    def test_must_be_osfstorage(self):
        self.file.provider = "github"
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {"data": {"id": self.file._id, "type": "files", "attributes": {"checkout": self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)

    def test_get_file_resolves_guids(self):
        guid = self.file.get_guid(create=True)
        url = "/{}files/{}/".format(API_BASE, guid._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ["data"])
        assert_equal(res.json["data"]["attributes"]["path"], self.file.path)

    def test_get_file_invalid_guid_gives_404(self):
        url = "/{}files/{}/".format(API_BASE, "asdasasd")
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_get_file_non_file_guid_gives_404(self):
        url = "/{}files/{}/".format(API_BASE, self.node._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_current_version_is_equal_to_length_of_history(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.json["data"]["attributes"]["current_version"], 1)
        for version in range(2, 4):
            self.file.create_version(
                self.user,
                {
                    "object": "06d80e" + str(version),
                    "service": "cloud",
                    osfstorage_settings.WATERBUTLER_RESOURCE: "osf",
                },
                {"size": 1337, "contentType": "img/png"},
            ).save()
            res = self.app.get(self.file_url, auth=self.user.auth)
            assert_equal(res.json["data"]["attributes"]["current_version"], version)
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)
        self.file = api_utils.create_test_file(self.node, self.user)

    def test_must_have_auth(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_get_file(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        attributes = res.json['data']['attributes']
        assert_equal(attributes['path'], self.file.path)
        assert_equal(attributes['kind'], self.file.kind)
        assert_equal(attributes['name'], self.file.name)
        assert_equal(attributes['materialized_path'], self.file.materialized_path)
        assert_equal(attributes['last_touched'], None)
        assert_equal(attributes['provider'], self.file.provider)
        assert_equal(attributes['size'], self.file.versions[-1].size)
        assert_equal(attributes['date_modified'], _dt_to_iso8601(self.file.versions[-1].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['date_created'], _dt_to_iso8601(self.file.versions[0].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['extra']['hashes']['md5'], None)
        assert_equal(attributes['extra']['hashes']['sha256'], None)


    def test_file_has_comments_link(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.node._id, self.file.get_guid()._id)
        url = res.json['data']['relationships']['comments']['links']['related']['href']
        assert_in(expected_url, url)

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node, target=self.file.get_guid(), user=contributor, page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments']['links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth
        )
        self.file.reload()
        self.file.save()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            auth=self.user.auth
        )
        assert_equal(len(self.node.logs),2)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)
        assert_equal(
            self.user._id,
            res.json['data']['relationships']['checkout']['links']['related']['meta']['id']
        )
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id),
            res.json['data']['relationships']['checkout']['links']['related']['href']
        )

        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'Wrong type.', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': '12345', 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files'}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_IN)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_admin_can_checkout(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_noncontrib_cannot_checkout(self):
        user = AuthUserFactory()
        assert_equal(self.file.checkout, None)
        assert user._id not in self.node.permissions.keys()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_read_contrib_cannot_checkout(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read'])
        self.node.save()
        assert_false(self.node.can_edit(user=user))
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=user.auth,
            expect_errors=True
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)
Exemple #4
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()

        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)

        self.osfstorage = self.node.get_addon('osfstorage')

        self.root_node = self.osfstorage.get_root()
        self.file = self.root_node.append_file('test_file')
        self.file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png'
        }).save()

    def test_must_have_auth(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_get_file(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(res.json['data']['attributes'], {
            'path': self.file.path,
            'kind': self.file.kind,
            'name': self.file.name,
            'last_touched': None,
            'provider': self.file.provider,
            'size': self.file.versions[-1].size,
            # HACK: odm's dates are weird
            'date_modified': self.file.versions[-1].date_created.isoformat()[:-3],
            'extra': {
                'hashes': {
                    'md5': None,
                    'sha256': None,
                },
            },
        })

    def test_file_has_comments_link(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.node._id, self.file._id)
        url = res.json['data']['relationships']['comments']['links']['related']['href']
        assert_in(expected_url, url)

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node, target=self.file, user=contributor, page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments']['links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            auth=self.user.auth
        )
        assert_equal(
            self.user._id,
            res.json['data']['relationships']['checkout']['links']['related']['meta']['id']
        )
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id),
            res.json['data']['relationships']['checkout']['links']['related']['href']
        )

        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'Wrong type.', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': '12345', 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files'}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_admin_can_checkout(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)
Exemple #5
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()

        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)

        self.osfstorage = self.node.get_addon('osfstorage')

        self.root_node = self.osfstorage.get_root()
        self.file = self.root_node.append_file('test_file')
        self.file.create_version(
            self.user, {
                'object': '06d80e',
                'service': 'cloud',
                osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
            }, {
                'size': 1337,
                'contentType': 'img/png'
            }).save()

    def test_must_have_auth(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           auth=user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_get_file(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(
            res.json['data']['attributes'], {
                'path': self.file.path,
                'kind': self.file.kind,
                'name': self.file.name,
                'size': self.file.versions[0].size,
                'provider': self.file.provider,
                'last_touched': None,
            })

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth)
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
                                    auth=self.user.auth)
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'id': self.file._id,
                'attributes': {
                    'checkout': self.user._id
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': self.file._id,
                    'type': 'Wrong type.',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'data': {
                    'id': '12345',
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api('/{}files/{}/'.format(
            API_BASE, self.file._id), {
                'id': self.file._id,
                'type': 'files'
            },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': user._id
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': user._id
                }
            },
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_admin_can_checkout(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)
Exemple #6
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user, comment_level='public')
        self.file = api_utils.create_test_file(self.node,
                                               self.user,
                                               create_guid=False)
        self.file_url = '/{}files/{}/'.format(API_BASE, self.file._id)

    def test_must_have_auth(self):
        res = self.app.get(self.file_url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get(self.file_url, auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_unvisited_file_has_no_guid(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['guid'], None)

    def test_visited_file_has_guid(self):
        guid = self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_is_not_none(guid)
        assert_equal(res.json['data']['attributes']['guid'], guid._id)

    def test_get_file(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        attributes = res.json['data']['attributes']
        assert_equal(attributes['path'], self.file.path)
        assert_equal(attributes['kind'], self.file.kind)
        assert_equal(attributes['name'], self.file.name)
        assert_equal(attributes['materialized_path'],
                     self.file.materialized_path)
        assert_equal(attributes['last_touched'], None)
        assert_equal(attributes['provider'], self.file.provider)
        assert_equal(attributes['size'], self.file.versions[-1].size)
        assert_equal(
            attributes['date_modified'],
            _dt_to_iso8601(
                self.file.versions[-1].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(
            attributes['date_created'],
            _dt_to_iso8601(
                self.file.versions[0].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['extra']['hashes']['md5'], None)
        assert_equal(attributes['extra']['hashes']['sha256'], None)
        assert_equal(attributes['tags'], [])

    def test_file_has_rel_link_to_owning_project(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('node', res.json['data']['relationships'].keys())
        expected_url = self.node.api_v2_url
        actual_url = res.json['data']['relationships']['node']['links'][
            'related']['href']
        assert_in(expected_url, actual_url)

    def test_file_has_comments_link(self):
        self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        url = res.json['data']['relationships']['comments']['links'][
            'related']['href']
        assert_equal(self.app.get(url, auth=self.user.auth).status_code, 200)
        assert_equal(res.json['data']['type'], 'files')

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node,
                                 target=self.file.get_guid(create=True),
                                 user=contributor,
                                 page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(
            API_BASE, self.file._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments'][
            'links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_only_project_contrib_can_comment_on_closed_project(self):
        self.node.comment_level = 'private'
        self.node.is_public = True
        self.node.save()

        res = self.app.get(self.file_url, auth=self.user.auth)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_any_loggedin_user_can_comment_on_open_project(self):
        self.node.is_public = True
        self.node.save()
        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

    def test_non_logged_in_user_cant_comment(self):
        self.node.is_public = True
        self.node.save()
        res = self.app.get(self.file_url)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth)
        self.file.reload()
        self.file.save()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(len(self.node.logs), 2)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)
        assert_equal(
            self.user._id, res.json['data']['relationships']['checkout']
            ['links']['related']['meta']['id'])
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id), res.json['data']
            ['relationships']['checkout']['links']['related']['href'])

        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': None
                }
            }
        },
                                    auth=self.user.auth)
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'Wrong type.',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': '12345',
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            self.file_url, {'data': {
                'id': self.file._id,
                'type': 'files'
            }},
            auth=self.user.auth,
            expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': user._id
                    }
                }
            },
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_IN)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_admin_can_checkout(self):
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_cannot_checkin_when_already_checked_in(self):
        count = len(self.node.logs)
        assert_false(self.file.is_checked_out)
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(len(self.node.logs), count)
        assert_equal(self.file.checkout, None)

    def test_cannot_checkout_when_checked_out(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        count = len(self.node.logs)
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, user)
        assert_equal(len(self.node.logs), count)

    def test_noncontrib_cannot_checkout(self):
        user = AuthUserFactory()
        assert_equal(self.file.checkout, None)
        assert user._id not in self.node.permissions.keys()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_read_contrib_cannot_checkout(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read'])
        self.node.save()
        assert_false(self.node.can_edit(user=user))
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': None
                }
            }
        },
                                    auth=user.auth,
                                    expect_errors=True)
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_removed_contrib_files_checked_in(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        assert_true(self.file.is_checked_out)
        with capture_signals() as mock_signals:
            self.node.remove_contributor(user, auth=Auth(user))
        assert_equal(mock_signals.signals_sent(), set([contributor_removed]))
        self.file.reload()
        assert_false(self.file.is_checked_out)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)

    def test_get_file_resolves_guids(self):
        guid = self.file.get_guid(create=True)
        url = '/{}files/{}/'.format(API_BASE, guid._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(res.json['data']['attributes']['path'], self.file.path)

    def test_get_file_invalid_guid_gives_404(self):
        url = '/{}files/{}/'.format(API_BASE, 'asdasasd')
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_get_file_non_file_guid_gives_404(self):
        url = '/{}files/{}/'.format(API_BASE, self.node._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)
Exemple #7
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user, comment_level='public')
        self.file = api_utils.create_test_file(self.node, self.user, create_guid=False)
        self.file_url = '/{}files/{}/'.format(API_BASE, self.file._id)

    def test_must_have_auth(self):
        res = self.app.get(self.file_url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get(self.file_url, auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_unvisited_file_has_no_guid(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['guid'], None)

    def test_visited_file_has_guid(self):
        guid = self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_is_not_none(guid)
        assert_equal(res.json['data']['attributes']['guid'], guid._id)

    def test_get_file(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        attributes = res.json['data']['attributes']
        assert_equal(attributes['path'], self.file.path)
        assert_equal(attributes['kind'], self.file.kind)
        assert_equal(attributes['name'], self.file.name)
        assert_equal(attributes['materialized_path'], self.file.materialized_path)
        assert_equal(attributes['last_touched'], None)
        assert_equal(attributes['provider'], self.file.provider)
        assert_equal(attributes['size'], self.file.versions[-1].size)
        assert_equal(attributes['date_modified'], _dt_to_iso8601(self.file.versions[-1].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['date_created'], _dt_to_iso8601(self.file.versions[0].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['extra']['hashes']['md5'], None)
        assert_equal(attributes['extra']['hashes']['sha256'], None)
        assert_equal(attributes['tags'], [])

    def test_file_has_rel_link_to_owning_project(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('node', res.json['data']['relationships'].keys())
        expected_url = self.node.api_v2_url
        actual_url = res.json['data']['relationships']['node']['links']['related']['href']
        assert_in(expected_url, actual_url)

    def test_file_has_comments_link(self):
        guid = self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.node._id, guid._id)
        url = res.json['data']['relationships']['comments']['links']['related']['href']
        assert_in(expected_url, url)

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node, target=self.file.get_guid(create=True), user=contributor, page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments']['links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_only_project_contrib_can_comment_on_closed_project(self):
        self.node.comment_level = 'private'
        self.node.is_public = True
        self.node.save()

        res = self.app.get(self.file_url, auth=self.user.auth)
        can_comment = res.json['data']['attributes']['current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json['data']['attributes']['current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_any_loggedin_user_can_comment_on_open_project(self):
        self.node.is_public = True
        self.node.save()
        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json['data']['attributes']['current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

    def test_non_logged_in_user_cant_comment(self):
        self.node.is_public = True
        self.node.save()
        res = self.app.get(self.file_url)
        can_comment = res.json['data']['attributes']['current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth
        )
        self.file.reload()
        self.file.save()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(
            self.file_url,
            auth=self.user.auth
        )
        assert_equal(len(self.node.logs),2)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)
        assert_equal(
            self.user._id,
            res.json['data']['relationships']['checkout']['links']['related']['meta']['id']
        )
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id),
            res.json['data']['relationships']['checkout']['links']['related']['href']
        )

        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'Wrong type.', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': '12345', 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files'}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_IN)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_admin_can_checkout(self):
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_cannot_checkin_when_already_checked_in(self):
        count = len(self.node.logs)
        assert_false(self.file.is_checked_out)
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(len(self.node.logs), count)
        assert_equal(self.file.checkout, None)

    def test_cannot_checkout_when_checked_out(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        count = len(self.node.logs)
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, user)
        assert_equal(len(self.node.logs), count)

    def test_noncontrib_cannot_checkout(self):
        user = AuthUserFactory()
        assert_equal(self.file.checkout, None)
        assert user._id not in self.node.permissions.keys()
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_read_contrib_cannot_checkout(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read'])
        self.node.save()
        assert_false(self.node.can_edit(user=user))
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=user.auth,
            expect_errors=True
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_removed_contrib_files_checked_in(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        assert_true(self.file.is_checked_out)
        with capture_signals() as mock_signals:
            self.node.remove_contributor(user, auth=Auth(user))
        assert_equal(mock_signals.signals_sent(), set([contributor_removed]))
        self.file.reload()
        assert_false(self.file.is_checked_out)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)

    def test_get_file_resolves_guids(self):
        guid = self.file.get_guid(create=True)
        url = '/{}files/{}/'.format(API_BASE, guid._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(res.json['data']['attributes']['path'], self.file.path)

    def test_get_file_invalid_guid_gives_404(self):
        url = '/{}files/{}/'.format(API_BASE, 'asdasasd')
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_get_file_non_file_guid_gives_404(self):
        url = '/{}files/{}/'.format(API_BASE, self.node._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)
Exemple #8
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()

        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)

        self.osfstorage = self.node.get_addon('osfstorage')

        self.root_node = self.osfstorage.get_root()
        self.file = self.root_node.append_file('test_file')
        self.file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png'
        }).save()

    def test_must_have_auth(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_get_file(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(res.json['data']['attributes'], {
            'path': self.file.path,
            'kind': self.file.kind,
            'name': self.file.name,
            'materialized_path': self.file.materialized_path,
            'last_touched': None,
            'provider': self.file.provider,
            'size': self.file.versions[-1].size,
            # HACK: odm's dates are weird
            'date_modified': _dt_to_iso8601(self.file.versions[-1].date_created.replace(tzinfo=pytz.utc)),
            'date_created': _dt_to_iso8601(self.file.versions[0].date_created.replace(tzinfo=pytz.utc)),
            'extra': {
                'hashes': {
                    'md5': None,
                    'sha256': None,
                },
            },
        })

    def test_file_has_comments_link(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.node._id, self.file._id)
        url = res.json['data']['relationships']['comments']['links']['related']['href']
        assert_in(expected_url, url)

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node, target=self.file, user=contributor, page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments']['links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            auth=self.user.auth
        )
        assert_equal(
            self.user._id,
            res.json['data']['relationships']['checkout']['links']['related']['meta']['id']
        )
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id),
            res.json['data']['relationships']['checkout']['links']['related']['href']
        )

        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'Wrong type.', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': '12345', 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files'}},
            auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': user._id}}},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_admin_can_checkout(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': None}}},
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'data': {'id': self.file._id, 'type': 'files', 'attributes': {'checkout': self.user._id}}},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)
Exemple #9
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()

        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)

        self.osfstorage = self.node.get_addon('osfstorage')

        self.root_node = self.osfstorage.get_root()
        self.file = self.root_node.append_file('test_file')
        self.file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png'
        }).save()

    def test_must_have_auth(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_get_file(self):
        res = self.app.get('/{}files/{}/'.format(API_BASE, self.file._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(res.json['data']['attributes'], {
            'path': self.file.path,
            'kind': self.file.kind,
            'name': self.file.name,
            'size': self.file.versions[0].size,
            'provider': self.file.provider,
            'last_touched': None,
        })

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': self.user._id},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': None},
            auth=self.user.auth
        )
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': user._id},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': user._id},
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': None},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_admin_can_checkout(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': self.user._id},
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': None},
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json(
            '/{}files/{}/'.format(API_BASE, self.file._id),
            {'checkout': self.user._id},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)
Exemple #10
0
class TestFileView(ApiTestCase):
    def setUp(self):
        super(TestFileView, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user, comment_level='public')
        self.file = api_utils.create_test_file(self.node,
                                               self.user,
                                               create_guid=False)
        self.file_url = '/{}files/{}/'.format(API_BASE, self.file._id)

    def test_must_have_auth(self):
        res = self.app.get(self.file_url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_must_be_contributor(self):
        user = AuthUserFactory()
        res = self.app.get(self.file_url, auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_unvisited_file_has_no_guid(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['guid'], None)

    def test_visited_file_has_guid(self):
        guid = self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_is_not_none(guid)
        assert_equal(res.json['data']['attributes']['guid'], guid._id)

    @mock.patch('api.base.throttling.CreateGuidThrottle.allow_request')
    def test_file_guid_not_created_with_basic_auth(self, mock_allow):
        res = self.app.get(self.file_url + '?create_guid=1',
                           auth=self.user.auth)
        guid = res.json['data']['attributes'].get('guid', None)
        assert_equal(res.status_code, 200)
        assert_equal(mock_allow.call_count, 1)
        assert guid is None

    @mock.patch('api.base.throttling.CreateGuidThrottle.allow_request')
    def test_file_guid_created_with_cookie(self, mock_allow):
        session = Session(data={'auth_user_id': self.user._id})
        session.save()
        cookie = itsdangerous.Signer(website_settings.SECRET_KEY).sign(
            session._id)
        self.app.set_cookie(website_settings.COOKIE_NAME, str(cookie))

        res = self.app.get(self.file_url + '?create_guid=1',
                           auth=self.user.auth)

        self.app.reset()  # clear cookie

        assert_equal(res.status_code, 200)

        guid = res.json['data']['attributes'].get('guid', None)
        assert_is_not_none(guid)

        assert_equal(guid, self.file.get_guid()._id)
        assert_equal(mock_allow.call_count, 1)

    def test_get_file(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        self.file.versions[-1]._clear_caches()
        self.file.versions[-1].reload()
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        attributes = res.json['data']['attributes']
        assert_equal(attributes['path'], self.file.path)
        assert_equal(attributes['kind'], self.file.kind)
        assert_equal(attributes['name'], self.file.name)
        assert_equal(attributes['materialized_path'],
                     self.file.materialized_path)
        assert_equal(attributes['last_touched'], None)
        assert_equal(attributes['provider'], self.file.provider)
        assert_equal(attributes['size'], self.file.versions[-1].size)
        assert_equal(attributes['current_version'], len(self.file.history))
        assert_equal(
            attributes['date_modified'],
            _dt_to_iso8601(
                self.file.versions[-1].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(
            attributes['date_created'],
            _dt_to_iso8601(
                self.file.versions[0].date_created.replace(tzinfo=pytz.utc)))
        assert_equal(attributes['extra']['hashes']['md5'], None)
        assert_equal(attributes['extra']['hashes']['sha256'], None)
        assert_equal(attributes['tags'], [])

    def test_file_has_rel_link_to_owning_project(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('node', res.json['data']['relationships'].keys())
        expected_url = self.node.api_v2_url
        actual_url = res.json['data']['relationships']['node']['links'][
            'related']['href']
        assert_in(expected_url, actual_url)

    def test_file_has_comments_link(self):
        self.file.get_guid(create=True)
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('comments', res.json['data']['relationships'].keys())
        url = res.json['data']['relationships']['comments']['links'][
            'related']['href']
        assert_equal(self.app.get(url, auth=self.user.auth).status_code, 200)
        assert_equal(res.json['data']['type'], 'files')

    def test_file_has_correct_unread_comments_count(self):
        contributor = AuthUserFactory()
        self.node.add_contributor(contributor, auth=Auth(self.user), save=True)
        comment = CommentFactory(node=self.node,
                                 target=self.file.get_guid(create=True),
                                 user=contributor,
                                 page='files')
        res = self.app.get('/{}files/{}/?related_counts=True'.format(
            API_BASE, self.file._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        unread_comments = res.json['data']['relationships']['comments'][
            'links']['related']['meta']['unread']
        assert_equal(unread_comments, 1)

    def test_only_project_contrib_can_comment_on_closed_project(self):
        self.node.comment_level = 'private'
        self.node.is_public = True
        self.node.save()

        res = self.app.get(self.file_url, auth=self.user.auth)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_any_loggedin_user_can_comment_on_open_project(self):
        self.node.is_public = True
        self.node.save()
        non_contributor = AuthUserFactory()
        res = self.app.get(self.file_url, auth=non_contributor.auth)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, True)

    def test_non_logged_in_user_cant_comment(self):
        self.node.is_public = True
        self.node.save()
        res = self.app.get(self.file_url)
        can_comment = res.json['data']['attributes'][
            'current_user_can_comment']
        assert_equal(res.status_code, 200)
        assert_equal(can_comment, False)

    def test_checkout(self):
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth)
        self.file.reload()
        self.file.save()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)

        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(len(self.node.logs), 2)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)
        assert_equal(
            self.user._id, res.json['data']['relationships']['checkout']
            ['links']['related']['meta']['id'])
        assert_in(
            '/{}users/{}/'.format(API_BASE, self.user._id), res.json['data']
            ['relationships']['checkout']['links']['related']['href'])

        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': None
                }
            }
        },
                                    auth=self.user.auth)
        self.file.reload()
        assert_equal(self.file.checkout, None)
        assert_equal(res.status_code, 200)

    def test_checkout_file_no_type(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_no_id(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_checkout_file_incorrect_type(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'Wrong type.',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_incorrect_id(self):
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': '12345',
                'type': 'files',
                'attributes': {
                    'checkout': self.user._id
                }
            }
        },
                                    auth=self.user.auth,
                                    expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_checkout_file_no_attributes(self):
        res = self.app.put_json_api(
            self.file_url, {'data': {
                'id': self.file._id,
                'type': 'files'
            }},
            auth=self.user.auth,
            expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_must_set_self(self):
        user = UserFactory()
        assert_equal(self.file.checkout, None)
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 400)
        assert_equal(self.file.checkout, None)

    def test_must_be_self(self):
        user = AuthUserFactory()
        self.file.checkout = self.user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': user._id
                    }
                }
            },
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, self.user)

    def test_admin_can_checkin(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_IN)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_admin_can_checkout(self):
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, self.user)
        assert_equal(self.node.logs[-1].action, NodeLog.CHECKED_OUT)
        assert_equal(self.node.logs[-1].user, self.user)

    def test_cannot_checkin_when_already_checked_in(self):
        count = len(self.node.logs)
        assert_false(self.file.is_checked_out)
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(len(self.node.logs), count)
        assert_equal(self.file.checkout, None)

    def test_cannot_checkout_when_checked_out(self):
        user = UserFactory()
        self.node.add_contributor(user)
        self.file.checkout = user
        self.file.save()
        count = len(self.node.logs)
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, user)
        assert_equal(len(self.node.logs), count)

    def test_noncontrib_cannot_checkout(self):
        user = AuthUserFactory()
        assert_equal(self.file.checkout, None)
        assert user._id not in self.node.permissions.keys()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=user.auth,
            expect_errors=True,
        )
        self.file.reload()
        self.node.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_read_contrib_cannot_checkout(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read'])
        self.node.save()
        assert_false(self.node.can_edit(user=user))
        res = self.app.put_json_api(self.file_url, {
            'data': {
                'id': self.file._id,
                'type': 'files',
                'attributes': {
                    'checkout': None
                }
            }
        },
                                    auth=user.auth,
                                    expect_errors=True)
        self.file.reload()
        assert_equal(res.status_code, 403)
        assert_equal(self.file.checkout, None)
        assert self.node.logs[-1].action != NodeLog.CHECKED_OUT

    def test_user_can_checkin(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': None
                    }
                }
            },
            auth=user.auth,
        )
        self.file.reload()
        assert_equal(res.status_code, 200)
        assert_equal(self.file.checkout, None)

    def test_removed_contrib_files_checked_in(self):
        user = AuthUserFactory()
        self.node.add_contributor(user, permissions=['read', 'write'])
        self.node.save()
        assert_true(self.node.can_edit(user=user))
        self.file.checkout = user
        self.file.save()
        assert_true(self.file.is_checked_out)
        with capture_signals() as mock_signals:
            self.node.remove_contributor(user, auth=Auth(user))
        assert_equal(mock_signals.signals_sent(), set([contributor_removed]))
        self.file.reload()
        assert_false(self.file.is_checked_out)

    def test_must_be_osfstorage(self):
        self.file.provider = 'github'
        self.file.save()
        res = self.app.put_json_api(
            self.file_url,
            {
                'data': {
                    'id': self.file._id,
                    'type': 'files',
                    'attributes': {
                        'checkout': self.user._id
                    }
                }
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)

    def test_get_file_resolves_guids(self):
        guid = self.file.get_guid(create=True)
        url = '/{}files/{}/'.format(API_BASE, guid._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json.keys(), ['data'])
        assert_equal(res.json['data']['attributes']['path'], self.file.path)

    def test_get_file_invalid_guid_gives_404(self):
        url = '/{}files/{}/'.format(API_BASE, 'asdasasd')
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_get_file_non_file_guid_gives_404(self):
        url = '/{}files/{}/'.format(API_BASE, self.node._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_current_version_is_equal_to_length_of_history(self):
        res = self.app.get(self.file_url, auth=self.user.auth)
        assert_equal(res.json['data']['attributes']['current_version'], 1)
        for version in range(2, 4):
            self.file.create_version(
                self.user, {
                    'object': '06d80e' + str(version),
                    'service': 'cloud',
                    osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
                }, {
                    'size': 1337,
                    'contentType': 'img/png'
                }).save()
            res = self.app.get(self.file_url, auth=self.user.auth)
            assert_equal(res.json['data']['attributes']['current_version'],
                         version)