Show More
@@ -1007,6 +1007,75 b' OUTPUT::' | |||||
1007 | } |
|
1007 | } | |
1008 | error: null |
|
1008 | error: null | |
1009 |
|
1009 | |||
|
1010 | get_changeset | |||
|
1011 | ^^^^^^^^^^^^^ | |||
|
1012 | ||||
|
1013 | Get information and review status for a given changeset. This command can only | |||
|
1014 | be executed using the api_key of a user with read permissions to the | |||
|
1015 | repository. | |||
|
1016 | ||||
|
1017 | INPUT:: | |||
|
1018 | ||||
|
1019 | id : <id_for_response> | |||
|
1020 | api_key : "<api_key>" | |||
|
1021 | method : "get_changeset" | |||
|
1022 | args: { | |||
|
1023 | "repoid" : "<reponame or repo_id>", | |||
|
1024 | "raw_id" : "<raw_id>", | |||
|
1025 | "with_reviews": "<bool> = Optional(False)" | |||
|
1026 | } | |||
|
1027 | ||||
|
1028 | OUTPUT:: | |||
|
1029 | ||||
|
1030 | id : <id_given_in_input> | |||
|
1031 | result: { | |||
|
1032 | "author": "<full_author>", | |||
|
1033 | "date": "<date_time_of_commit>", | |||
|
1034 | "message": "<commit_message>", | |||
|
1035 | "raw_id": "<raw_id>", | |||
|
1036 | "revision": "<numeric_revision>", | |||
|
1037 | "short_id": "<short_id>", | |||
|
1038 | "reviews": [{ | |||
|
1039 | "reviewer": "<username>", | |||
|
1040 | "modified_at": "<date_time_of_review>", # iso 8601 date, server's timezone | |||
|
1041 | "status": "<status_of_review>", # "under_review", "approved" or "rejected" | |||
|
1042 | }, | |||
|
1043 | ... | |||
|
1044 | ] | |||
|
1045 | } | |||
|
1046 | error: null | |||
|
1047 | ||||
|
1048 | Example output:: | |||
|
1049 | ||||
|
1050 | { | |||
|
1051 | "id" : 1, | |||
|
1052 | "error" : null, | |||
|
1053 | "result" : { | |||
|
1054 | "author" : { | |||
|
1055 | "email" : "user@example.com", | |||
|
1056 | "name" : "Kallithea Admin" | |||
|
1057 | }, | |||
|
1058 | "changed" : [], | |||
|
1059 | "short_id" : "e1022d3d28df", | |||
|
1060 | "date" : "2017-03-28T09:09:03", | |||
|
1061 | "added" : [ | |||
|
1062 | "README.rst" | |||
|
1063 | ], | |||
|
1064 | "removed" : [], | |||
|
1065 | "revision" : 0, | |||
|
1066 | "raw_id" : "e1022d3d28dfba02f626cde65dbe08f4ceb0e4e7", | |||
|
1067 | "message" : "Added file via Kallithea", | |||
|
1068 | "id" : "e1022d3d28dfba02f626cde65dbe08f4ceb0e4e7", | |||
|
1069 | "reviews" : [ | |||
|
1070 | { | |||
|
1071 | "status" : "under_review", | |||
|
1072 | "modified_at" : "2017-03-28T09:17:08.618", | |||
|
1073 | "reviewer" : "user" | |||
|
1074 | } | |||
|
1075 | ] | |||
|
1076 | } | |||
|
1077 | } | |||
|
1078 | ||||
1010 |
|
1079 | |||
1011 | API access for web views |
|
1080 | API access for web views | |
1012 | ------------------------ |
|
1081 | ------------------------ |
@@ -47,12 +47,15 b' from kallithea.model.repo import RepoMod' | |||||
47 | from kallithea.model.user import UserModel |
|
47 | from kallithea.model.user import UserModel | |
48 | from kallithea.model.user_group import UserGroupModel |
|
48 | from kallithea.model.user_group import UserGroupModel | |
49 | from kallithea.model.gist import GistModel |
|
49 | from kallithea.model.gist import GistModel | |
|
50 | from kallithea.model.changeset_status import ChangesetStatusModel | |||
50 | from kallithea.model.db import ( |
|
51 | from kallithea.model.db import ( | |
51 | Repository, Setting, UserIpMap, Permission, User, Gist, |
|
52 | Repository, Setting, UserIpMap, Permission, User, Gist, | |
52 | RepoGroup, UserGroup) |
|
53 | RepoGroup, UserGroup) | |
53 | from kallithea.lib.compat import json |
|
54 | from kallithea.lib.compat import json | |
54 | from kallithea.lib.exceptions import ( |
|
55 | from kallithea.lib.exceptions import ( | |
55 | DefaultUserException, UserGroupsAssignedException) |
|
56 | DefaultUserException, UserGroupsAssignedException) | |
|
57 | from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError | |||
|
58 | from kallithea.lib.vcs.backends.base import EmptyChangeset | |||
56 |
|
59 | |||
57 | log = logging.getLogger(__name__) |
|
60 | log = logging.getLogger(__name__) | |
58 |
|
61 | |||
@@ -2469,3 +2472,22 b' class ApiController(JSONRPCController):' | |||||
2469 | log.error(traceback.format_exc()) |
|
2472 | log.error(traceback.format_exc()) | |
2470 | raise JSONRPCError('failed to delete gist ID:%s' |
|
2473 | raise JSONRPCError('failed to delete gist ID:%s' | |
2471 | % (gist.gist_access_id,)) |
|
2474 | % (gist.gist_access_id,)) | |
|
2475 | ||||
|
2476 | # permission check inside | |||
|
2477 | def get_changeset(self, repoid, raw_id, with_reviews=Optional(False)): | |||
|
2478 | repo = get_repo_or_error(repoid) | |||
|
2479 | if not HasRepoPermissionLevel('read')(repo.repo_name): | |||
|
2480 | raise JSONRPCError('Access denied to repo %s' % repo.repo_name) | |||
|
2481 | changeset = repo.get_changeset(raw_id) | |||
|
2482 | if isinstance(changeset, EmptyChangeset): | |||
|
2483 | raise JSONRPCError('Changeset %s does not exist' % raw_id) | |||
|
2484 | ||||
|
2485 | info = dict(changeset.as_dict()) | |||
|
2486 | ||||
|
2487 | with_reviews = Optional.extract(with_reviews) | |||
|
2488 | if with_reviews: | |||
|
2489 | reviews = ChangesetStatusModel().get_statuses( | |||
|
2490 | repo.repo_name, raw_id) | |||
|
2491 | info["reviews"] = reviews | |||
|
2492 | ||||
|
2493 | return info |
@@ -2287,6 +2287,13 b' class ChangesetStatus(Base, BaseDbModel)' | |||||
2287 | def status_lbl(self): |
|
2287 | def status_lbl(self): | |
2288 | return ChangesetStatus.get_status_lbl(self.status) |
|
2288 | return ChangesetStatus.get_status_lbl(self.status) | |
2289 |
|
2289 | |||
|
2290 | def __json__(self): | |||
|
2291 | return dict( | |||
|
2292 | status=self.status, | |||
|
2293 | modified_at=self.modified_at, | |||
|
2294 | reviewer=self.author.username, | |||
|
2295 | ) | |||
|
2296 | ||||
2290 |
|
2297 | |||
2291 | class PullRequest(Base, BaseDbModel): |
|
2298 | class PullRequest(Base, BaseDbModel): | |
2292 | __tablename__ = 'pull_requests' |
|
2299 | __tablename__ = 'pull_requests' |
@@ -2449,3 +2449,51 b' class _BaseTestApi(object):' | |||||
2449 | response = api_call(self, params) |
|
2449 | response = api_call(self, params) | |
2450 | expected = Setting.get_server_info() |
|
2450 | expected = Setting.get_server_info() | |
2451 | self._compare_ok(id_, expected, given=response.body) |
|
2451 | self._compare_ok(id_, expected, given=response.body) | |
|
2452 | ||||
|
2453 | def test_api_get_changeset(self): | |||
|
2454 | review = fixture.review_changeset(self.REPO, self.TEST_REVISION, "approved") | |||
|
2455 | id_, params = _build_data(self.apikey, 'get_changeset', | |||
|
2456 | repoid=self.REPO, raw_id = self.TEST_REVISION) | |||
|
2457 | response = api_call(self, params) | |||
|
2458 | result = json.loads(response.body)["result"] | |||
|
2459 | assert result["raw_id"] == self.TEST_REVISION | |||
|
2460 | assert not result.has_key("reviews") | |||
|
2461 | ||||
|
2462 | def test_api_get_changeset_with_reviews(self): | |||
|
2463 | reviewobjs = fixture.review_changeset(self.REPO, self.TEST_REVISION, "approved") | |||
|
2464 | id_, params = _build_data(self.apikey, 'get_changeset', | |||
|
2465 | repoid=self.REPO, raw_id = self.TEST_REVISION, | |||
|
2466 | with_reviews = True) | |||
|
2467 | response = api_call(self, params) | |||
|
2468 | result = json.loads(response.body)["result"] | |||
|
2469 | assert result["raw_id"] == self.TEST_REVISION | |||
|
2470 | assert result.has_key("reviews") | |||
|
2471 | assert len(result["reviews"]) == 1 | |||
|
2472 | review = result["reviews"][0] | |||
|
2473 | expected = { | |||
|
2474 | 'status': 'approved', | |||
|
2475 | 'modified_at': reviewobjs[0].modified_at.isoformat()[:-3], | |||
|
2476 | 'reviewer': 'test_admin', | |||
|
2477 | } | |||
|
2478 | assert review == expected | |||
|
2479 | ||||
|
2480 | def test_api_get_changeset_that_does_not_exist(self): | |||
|
2481 | """ Fetch changeset status for non-existant changeset. | |||
|
2482 | revision id is the above git hash used in the test above with the | |||
|
2483 | last 3 nibbles replaced with 0xf. Should not exist for git _or_ hg. | |||
|
2484 | """ | |||
|
2485 | id_, params = _build_data(self.apikey, 'get_changeset', | |||
|
2486 | repoid=self.REPO, raw_id = '7ab37bc680b4aa72c34d07b230c866c28e9fcfff') | |||
|
2487 | response = api_call(self, params) | |||
|
2488 | expected = u'Changeset %s does not exist' % ('7ab37bc680b4aa72c34d07b230c866c28e9fcfff',) | |||
|
2489 | self._compare_error(id_, expected, given=response.body) | |||
|
2490 | ||||
|
2491 | def test_api_get_changeset_without_permission(self): | |||
|
2492 | review = fixture.review_changeset(self.REPO, self.TEST_REVISION, "approved") | |||
|
2493 | RepoModel().revoke_user_permission(repo=self.REPO, user=self.TEST_USER_LOGIN) | |||
|
2494 | RepoModel().revoke_user_permission(repo=self.REPO, user="default") | |||
|
2495 | id_, params = _build_data(self.apikey_regular, 'get_changeset', | |||
|
2496 | repoid=self.REPO, raw_id = self.TEST_REVISION) | |||
|
2497 | response = api_call(self, params) | |||
|
2498 | expected = u'Access denied to repo %s' % self.REPO | |||
|
2499 | self._compare_error(id_, expected, given=response.body) |
@@ -12,10 +12,11 b'' | |||||
12 | # You should have received a copy of the GNU General Public License |
|
12 | # You should have received a copy of the GNU General Public License | |
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14 |
|
14 | |||
15 | from kallithea.tests.base import TestController, GIT_REPO |
|
15 | from kallithea.tests.base import TestController, GIT_REPO, GIT_TEST_REVISION | |
16 | from kallithea.tests.api.api_base import _BaseTestApi |
|
16 | from kallithea.tests.api.api_base import _BaseTestApi | |
17 |
|
17 | |||
18 |
|
18 | |||
19 | class TestGitApi(_BaseTestApi, TestController): |
|
19 | class TestGitApi(_BaseTestApi, TestController): | |
20 | REPO = GIT_REPO |
|
20 | REPO = GIT_REPO | |
21 | REPO_TYPE = 'git' |
|
21 | REPO_TYPE = 'git' | |
|
22 | TEST_REVISION = GIT_TEST_REVISION |
@@ -12,10 +12,11 b'' | |||||
12 | # You should have received a copy of the GNU General Public License |
|
12 | # You should have received a copy of the GNU General Public License | |
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14 |
|
14 | |||
15 | from kallithea.tests.base import TestController, HG_REPO |
|
15 | from kallithea.tests.base import TestController, HG_REPO, HG_TEST_REVISION | |
16 | from kallithea.tests.api.api_base import _BaseTestApi |
|
16 | from kallithea.tests.api.api_base import _BaseTestApi | |
17 |
|
17 | |||
18 |
|
18 | |||
19 | class TestHgApi(_BaseTestApi, TestController): |
|
19 | class TestHgApi(_BaseTestApi, TestController): | |
20 | REPO = HG_REPO |
|
20 | REPO = HG_REPO | |
21 | REPO_TYPE = 'hg' |
|
21 | REPO_TYPE = 'hg' | |
|
22 | TEST_REVISION = HG_TEST_REVISION |
@@ -48,7 +48,7 b' testapp = None' | |||||
48 | 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO', |
|
48 | 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO', | |
49 | 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO', |
|
49 | 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO', | |
50 | 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'HG_REMOTE_REPO', |
|
50 | 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'HG_REMOTE_REPO', | |
51 | 'GIT_REMOTE_REPO', 'SCM_TESTS', |
|
51 | 'GIT_REMOTE_REPO', 'SCM_TESTS', 'HG_TEST_REVISION', 'GIT_TEST_REVISION', | |
52 | ] |
|
52 | ] | |
53 |
|
53 | |||
54 | # Invoke websetup with the current config file |
|
54 | # Invoke websetup with the current config file | |
@@ -80,6 +80,10 b" NEW_GIT_REPO = u'vcs_test_git_new'" | |||||
80 | HG_FORK = u'vcs_test_hg_fork' |
|
80 | HG_FORK = u'vcs_test_hg_fork' | |
81 | GIT_FORK = u'vcs_test_git_fork' |
|
81 | GIT_FORK = u'vcs_test_git_fork' | |
82 |
|
82 | |||
|
83 | HG_TEST_REVISION = u"a53d9201d4bc278910d416d94941b7ea007ecd52" | |||
|
84 | GIT_TEST_REVISION = u"7ab37bc680b4aa72c34d07b230c866c28e9fc204" | |||
|
85 | ||||
|
86 | ||||
83 | ## VCS |
|
87 | ## VCS | |
84 | SCM_TESTS = ['hg', 'git'] |
|
88 | SCM_TESTS = ['hg', 'git'] | |
85 | uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple()))) |
|
89 | uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple()))) |
@@ -22,7 +22,7 b' import shutil' | |||||
22 | import tarfile |
|
22 | import tarfile | |
23 | from os.path import dirname |
|
23 | from os.path import dirname | |
24 |
|
24 | |||
25 | from kallithea.model.db import Repository, User, RepoGroup, UserGroup, Gist |
|
25 | from kallithea.model.db import Repository, User, RepoGroup, UserGroup, Gist, ChangesetStatus | |
26 | from kallithea.model.meta import Session |
|
26 | from kallithea.model.meta import Session | |
27 | from kallithea.model.repo import RepoModel |
|
27 | from kallithea.model.repo import RepoModel | |
28 | from kallithea.model.user import UserModel |
|
28 | from kallithea.model.user import UserModel | |
@@ -30,6 +30,8 b' from kallithea.model.repo_group import R' | |||||
30 | from kallithea.model.user_group import UserGroupModel |
|
30 | from kallithea.model.user_group import UserGroupModel | |
31 | from kallithea.model.gist import GistModel |
|
31 | from kallithea.model.gist import GistModel | |
32 | from kallithea.model.scm import ScmModel |
|
32 | from kallithea.model.scm import ScmModel | |
|
33 | from kallithea.model.comment import ChangesetCommentsModel | |||
|
34 | from kallithea.model.changeset_status import ChangesetStatusModel | |||
33 | from kallithea.lib.db_manage import DbManage |
|
35 | from kallithea.lib.db_manage import DbManage | |
34 | from kallithea.lib.vcs.backends.base import EmptyChangeset |
|
36 | from kallithea.lib.vcs.backends.base import EmptyChangeset | |
35 | from kallithea.tests.base import invalidate_all_caches, GIT_REPO, HG_REPO, TESTS_TMP_PATH, TEST_USER_ADMIN_LOGIN |
|
37 | from kallithea.tests.base import invalidate_all_caches, GIT_REPO, HG_REPO, TESTS_TMP_PATH, TEST_USER_ADMIN_LOGIN | |
@@ -309,6 +311,12 b' class Fixture(object):' | |||||
309 | ) |
|
311 | ) | |
310 | return cs |
|
312 | return cs | |
311 |
|
313 | |||
|
314 | def review_changeset(self, repo, revision, status, author=TEST_USER_ADMIN_LOGIN): | |||
|
315 | comment = ChangesetCommentsModel().create(u"review comment", repo, author, revision=revision, send_email=False) | |||
|
316 | csm = ChangesetStatusModel().set_status(repo, ChangesetStatus.STATUS_APPROVED, author, comment, revision=revision) | |||
|
317 | Session().commit() | |||
|
318 | return csm | |||
|
319 | ||||
312 |
|
320 | |||
313 | #============================================================================== |
|
321 | #============================================================================== | |
314 | # Global test environment setup |
|
322 | # Global test environment setup |
General Comments 0
You need to be logged in to leave comments.
Login now