Show More
@@ -40,7 +40,7 b' from rhodecode.admin.navigation import n' | |||
|
40 | 40 | from rhodecode.translation import _ |
|
41 | 41 | from rhodecode.integrations import integration_type_registry |
|
42 | 42 | from rhodecode.model.validation_schema.schemas.integration_schema import ( |
|
43 | make_integration_schema) | |
|
43 | make_integration_schema, IntegrationScopeType) | |
|
44 | 44 | |
|
45 | 45 | log = logging.getLogger(__name__) |
|
46 | 46 | |
@@ -151,7 +151,11 b' class IntegrationSettingsViewBase(object' | |||
|
151 | 151 | defaults['options'] = { |
|
152 | 152 | 'name': self.integration.name, |
|
153 | 153 | 'enabled': self.integration.enabled, |
|
154 |
'scope': |
|
|
154 | 'scope': { | |
|
155 | 'repo': self.integration.repo, | |
|
156 | 'repo_group': self.integration.repo_group, | |
|
157 | 'child_repos_only': self.integration.child_repos_only, | |
|
158 | }, | |
|
155 | 159 | } |
|
156 | 160 | else: |
|
157 | 161 | if self.repo: |
@@ -168,10 +172,10 b' class IntegrationSettingsViewBase(object' | |||
|
168 | 172 | 'name': _('{name} integration').format( |
|
169 | 173 | name=self.IntegrationType.display_name), |
|
170 | 174 | } |
|
171 | if self.repo: | |
|
172 |
|
|
|
173 |
|
|
|
174 | defaults['options']['scope'] = self.repo_group | |
|
175 | defaults['options']['scope'] = { | |
|
176 | 'repo': self.repo, | |
|
177 | 'repo_group': self.repo_group, | |
|
178 | } | |
|
175 | 179 | |
|
176 | 180 | return defaults |
|
177 | 181 | |
@@ -250,11 +254,10 b' class IntegrationSettingsViewBase(object' | |||
|
250 | 254 | # scope is read only field in these cases, and has to be added |
|
251 | 255 | options = pstruct.setdefault('options', {}) |
|
252 | 256 | if 'scope' not in options: |
|
253 | if self.repo: | |
|
254 |
|
|
|
255 |
|
|
|
256 | options['scope'] = 'repogroup:{}'.format( | |
|
257 | self.repo_group.group_name) | |
|
257 | options['scope'] = IntegrationScopeType().serialize(None, { | |
|
258 | 'repo': self.repo, | |
|
259 | 'repo_group': self.repo_group, | |
|
260 | }) | |
|
258 | 261 | |
|
259 | 262 | try: |
|
260 | 263 | valid_data = form.validate_pstruct(pstruct) |
@@ -276,7 +279,11 b' class IntegrationSettingsViewBase(object' | |||
|
276 | 279 | name=valid_data['options']['name'], |
|
277 | 280 | enabled=valid_data['options']['enabled'], |
|
278 | 281 | settings=valid_data['settings'], |
|
279 |
|
|
|
282 | repo=scope['repo'], | |
|
283 | repo_group=scope['repo_group'], | |
|
284 | child_repos_only=scope['child_repos_only'], | |
|
285 | ) | |
|
286 | ||
|
280 | 287 | |
|
281 | 288 | self.integration.settings = valid_data['settings'] |
|
282 | 289 | Session().commit() |
@@ -291,16 +298,16 b' class IntegrationSettingsViewBase(object' | |||
|
291 | 298 | # keeping in mind if the original view was for /repo/ or /_admin/ |
|
292 | 299 | admin_view = not (self.repo or self.repo_group) |
|
293 | 300 | |
|
294 |
if |
|
|
301 | if self.integration.repo and not admin_view: | |
|
295 | 302 | redirect_to = self.request.route_path( |
|
296 | 303 | 'repo_integrations_edit', |
|
297 |
repo_name=self.integration. |
|
|
304 | repo_name=self.integration.repo.repo_name, | |
|
298 | 305 | integration=self.integration.integration_type, |
|
299 | 306 | integration_id=self.integration.integration_id) |
|
300 |
elif |
|
|
307 | elif self.integration.repo_group and not admin_view: | |
|
301 | 308 | redirect_to = self.request.route_path( |
|
302 | 309 | 'repo_group_integrations_edit', |
|
303 |
repo_group_name=self.integration. |
|
|
310 | repo_group_name=self.integration.repo_group.group_name, | |
|
304 | 311 | integration=self.integration.integration_type, |
|
305 | 312 | integration_id=self.integration.integration_id) |
|
306 | 313 | else: |
@@ -3499,36 +3499,18 b' class Integration(Base, BaseModel):' | |||
|
3499 | 3499 | nullable=True, unique=None, default=None) |
|
3500 | 3500 | repo_group = relationship('RepoGroup', lazy='joined') |
|
3501 | 3501 | |
|
3502 |
@ |
|
|
3502 | @property | |
|
3503 | 3503 | def scope(self): |
|
3504 | 3504 | if self.repo: |
|
3505 | return self.repo | |
|
3505 | return repr(self.repo) | |
|
3506 | 3506 | if self.repo_group: |
|
3507 |
|
|
|
3507 | if self.child_repos_only: | |
|
3508 | return repr(self.repo_group) + ' (child repos only)' | |
|
3509 | else: | |
|
3510 | return repr(self.repo_group) + ' (recursive)' | |
|
3508 | 3511 | if self.child_repos_only: |
|
3509 | 3512 | return 'root_repos' |
|
3510 | 3513 | return 'global' |
|
3511 | 3514 | |
|
3512 | @scope.setter | |
|
3513 | def scope(self, value): | |
|
3514 | self.repo = None | |
|
3515 | self.repo_id = None | |
|
3516 | self.repo_group_id = None | |
|
3517 | self.repo_group = None | |
|
3518 | self.child_repos_only = False | |
|
3519 | if isinstance(value, Repository): | |
|
3520 | self.repo_id = value.repo_id | |
|
3521 | self.repo = value | |
|
3522 | elif isinstance(value, RepoGroup): | |
|
3523 | self.repo_group_id = value.group_id | |
|
3524 | self.repo_group = value | |
|
3525 | elif value == 'root_repos': | |
|
3526 | self.child_repos_only = True | |
|
3527 | elif value == 'global': | |
|
3528 | pass | |
|
3529 | else: | |
|
3530 | raise Exception("invalid scope: %s, must be one of " | |
|
3531 | "['global', 'root_repos', <RepoGroup>. <Repository>]" % value) | |
|
3532 | ||
|
3533 | 3515 | def __repr__(self): |
|
3534 | 3516 | return '<Integration(%r, %r)>' % (self.integration_type, self.scope) |
@@ -61,23 +61,24 b' class IntegrationModel(BaseModel):' | |||
|
61 | 61 | raise Exception('integration must be int, long or Instance' |
|
62 | 62 | ' of Integration got %s' % type(integration)) |
|
63 | 63 | |
|
64 |
def create(self, IntegrationType, name, enabled, |
|
|
64 | def create(self, IntegrationType, name, enabled, repo, repo_group, | |
|
65 | child_repos_only, settings): | |
|
65 | 66 | """ Create an IntegrationType integration """ |
|
66 | 67 | integration = Integration() |
|
67 | 68 | integration.integration_type = IntegrationType.key |
|
68 | 69 | self.sa.add(integration) |
|
69 |
self.update_integration(integration, name, enabled, |
|
|
70 | self.update_integration(integration, name, enabled, repo, repo_group, | |
|
71 | child_repos_only, settings) | |
|
70 | 72 | self.sa.commit() |
|
71 | 73 | return integration |
|
72 | 74 | |
|
73 |
def update_integration(self, integration, name, enabled, |
|
|
74 | """ | |
|
75 | :param scope: one of ['global', 'root_repos', <RepoGroup>. <Repository>] | |
|
76 | """ | |
|
77 | ||
|
75 | def update_integration(self, integration, name, enabled, repo, repo_group, | |
|
76 | child_repos_only, settings): | |
|
78 | 77 | integration = self.__get_integration(integration) |
|
79 | 78 | |
|
80 |
integration. |
|
|
79 | integration.repo = repo | |
|
80 | integration.repo_group = repo_group | |
|
81 | integration.child_repos_only = child_repos_only | |
|
81 | 82 | integration.name = name |
|
82 | 83 | integration.enabled = enabled |
|
83 | 84 | integration.settings = settings |
@@ -127,7 +128,7 b' class IntegrationModel(BaseModel):' | |||
|
127 | 128 | query = self.sa.query(Integration).filter( |
|
128 | 129 | and_(Integration.repo_id==None, Integration.repo_group_id==None) |
|
129 | 130 | ) |
|
130 |
elif scope == 'root |
|
|
131 | elif scope == 'root-repos': | |
|
131 | 132 | query = self.sa.query(Integration).filter( |
|
132 | 133 | and_(Integration.repo_id==None, |
|
133 | 134 | Integration.repo_group_id==None, |
@@ -185,13 +186,21 b' class IntegrationModel(BaseModel):' | |||
|
185 | 186 | |
|
186 | 187 | if event.repo.group: |
|
187 | 188 | clauses.append( |
|
188 | Integration.repo_group_id == event.repo.group.group_id | |
|
189 | and_( | |
|
190 | Integration.repo_group_id==event.repo.group.group_id, | |
|
191 | Integration.child_repos_only==True | |
|
192 | ) | |
|
189 | 193 | ) |
|
190 |
# repo group cascade to kids |
|
|
191 |
|
|
|
192 | # [group.group_id for group in | |
|
193 |
|
|
|
194 | # )) | |
|
194 | # repo group cascade to kids | |
|
195 | clauses.append( | |
|
196 | and_( | |
|
197 | Integration.repo_group_id.in_( | |
|
198 | [group.group_id for group in | |
|
199 | event.repo.groups_with_parents] | |
|
200 | ), | |
|
201 | Integration.child_repos_only==False | |
|
202 | ) | |
|
203 | ) | |
|
195 | 204 | |
|
196 | 205 | |
|
197 | 206 | if not event.repo.group: # root repo |
@@ -37,7 +37,7 b' def integration_scope_choices(permission' | |||
|
37 | 37 | if 'hg.admin' in permissions['global']: |
|
38 | 38 | result.extend([ |
|
39 | 39 | ('global', _('Global (all repositories)')), |
|
40 |
('root |
|
|
40 | ('root-repos', _('Top level repositories only')), | |
|
41 | 41 | ]) |
|
42 | 42 | |
|
43 | 43 | repo_choices = [ |
@@ -47,13 +47,19 b' def integration_scope_choices(permission' | |||
|
47 | 47 | if repo_perm == 'repository.admin' |
|
48 | 48 | ] |
|
49 | 49 | repogroup_choices = [ |
|
50 |
('repogroup:%s' % repo_group_name, '/' + repo_group_name + ' |
|
|
50 | ('repogroup:%s' % repo_group_name, '/' + repo_group_name + '/ (child repos only)') | |
|
51 | for repo_group_name, repo_group_perm | |
|
52 | in permissions['repositories_groups'].items() | |
|
53 | if repo_group_perm == 'group.admin' | |
|
54 | ] | |
|
55 | repogroup_recursive_choices = [ | |
|
56 | ('repogroup-recursive:%s' % repo_group_name, '/' + repo_group_name + '/ (recursive)') | |
|
51 | 57 | for repo_group_name, repo_group_perm |
|
52 | 58 | in permissions['repositories_groups'].items() |
|
53 | 59 | if repo_group_perm == 'group.admin' |
|
54 | 60 | ] |
|
55 | 61 | result.extend( |
|
56 | sorted(repogroup_choices + repo_choices, | |
|
62 | sorted(repogroup_recursive_choices + repogroup_choices + repo_choices, | |
|
57 | 63 | key=lambda (choice, label): choice.split(':', 1)[1] |
|
58 | 64 | ) |
|
59 | 65 | ) |
@@ -66,27 +72,24 b' def deferred_integration_scopes_validato' | |||
|
66 | 72 | def _scope_validator(_node, scope): |
|
67 | 73 | is_super_admin = 'hg.admin' in perms['global'] |
|
68 | 74 | |
|
69 |
if scope |
|
|
75 | if scope.get('repo'): | |
|
76 | if (is_super_admin or perms['repositories'].get( | |
|
77 | scope['repo'].repo_name) == 'repository.admin'): | |
|
78 | return True | |
|
79 | msg = _('Only repo admins can create integrations') | |
|
80 | raise colander.Invalid(_node, msg) | |
|
81 | elif scope.get('repo_group'): | |
|
82 | if (is_super_admin or perms['repositories_groups'].get( | |
|
83 | scope['repo_group'].group_name) == 'group.admin'): | |
|
84 | return True | |
|
85 | ||
|
86 | msg = _('Only repogroup admins can create integrations') | |
|
87 | raise colander.Invalid(_node, msg) | |
|
88 | else: | |
|
70 | 89 | if is_super_admin: |
|
71 | 90 | return True |
|
72 | 91 | msg = _('Only superadmins can create global integrations') |
|
73 | 92 | raise colander.Invalid(_node, msg) |
|
74 | elif isinstance(scope, Repository): | |
|
75 | if (is_super_admin or perms['repositories'].get( | |
|
76 | scope.repo_name) == 'repository.admin'): | |
|
77 | return True | |
|
78 | msg = _('Only repo admins can create integrations') | |
|
79 | raise colander.Invalid(_node, msg) | |
|
80 | elif isinstance(scope, RepoGroup): | |
|
81 | if (is_super_admin or perms['repositories_groups'].get( | |
|
82 | scope.group_name) == 'group.admin'): | |
|
83 | return True | |
|
84 | ||
|
85 | msg = _('Only repogroup admins can create integrations') | |
|
86 | raise colander.Invalid(_node, msg) | |
|
87 | ||
|
88 | msg = _('Invalid integration scope: %s' % scope) | |
|
89 | raise colander.Invalid(node, msg) | |
|
90 | 93 | |
|
91 | 94 | return _scope_validator |
|
92 | 95 | |
@@ -100,17 +103,26 b' def deferred_integration_scopes_widget(n' | |||
|
100 | 103 | widget = deform.widget.Select2Widget(values=choices) |
|
101 | 104 | return widget |
|
102 | 105 | |
|
103 | class IntegrationScope(colander.SchemaType): | |
|
106 | ||
|
107 | class IntegrationScopeType(colander.SchemaType): | |
|
104 | 108 | def serialize(self, node, appstruct): |
|
105 | 109 | if appstruct is colander.null: |
|
106 | 110 | return colander.null |
|
107 | 111 | |
|
108 |
if |
|
|
109 | return 'repo:%s' % appstruct.repo_name | |
|
110 |
elif |
|
|
111 | return 'repogroup:%s' % appstruct.group_name | |
|
112 | elif appstruct in ('global', 'root_repos'): | |
|
113 |
|
|
|
112 | if appstruct.get('repo'): | |
|
113 | return 'repo:%s' % appstruct['repo'].repo_name | |
|
114 | elif appstruct.get('repo_group'): | |
|
115 | if appstruct.get('child_repos_only'): | |
|
116 | return 'repogroup:%s' % appstruct['repo_group'].group_name | |
|
117 | else: | |
|
118 | return 'repogroup-recursive:%s' % ( | |
|
119 | appstruct['repo_group'].group_name) | |
|
120 | else: | |
|
121 | if appstruct.get('child_repos_only'): | |
|
122 | return 'root-repos' | |
|
123 | else: | |
|
124 | return 'global' | |
|
125 | ||
|
114 | 126 | raise colander.Invalid(node, '%r is not a valid scope' % appstruct) |
|
115 | 127 | |
|
116 | 128 | def deserialize(self, node, cstruct): |
@@ -120,16 +132,43 b' class IntegrationScope(colander.SchemaTy' | |||
|
120 | 132 | if cstruct.startswith('repo:'): |
|
121 | 133 | repo = Repository.get_by_repo_name(cstruct.split(':')[1]) |
|
122 | 134 | if repo: |
|
123 |
return |
|
|
135 | return { | |
|
136 | 'repo': repo, | |
|
137 | 'repo_group': None, | |
|
138 | 'child_repos_only': None, | |
|
139 | } | |
|
140 | elif cstruct.startswith('repogroup-recursive:'): | |
|
141 | repo_group = RepoGroup.get_by_group_name(cstruct.split(':')[1]) | |
|
142 | if repo_group: | |
|
143 | return { | |
|
144 | 'repo': None, | |
|
145 | 'repo_group': repo_group, | |
|
146 | 'child_repos_only': False | |
|
147 | } | |
|
124 | 148 | elif cstruct.startswith('repogroup:'): |
|
125 | 149 | repo_group = RepoGroup.get_by_group_name(cstruct.split(':')[1]) |
|
126 | 150 | if repo_group: |
|
127 |
return |
|
|
128 | elif cstruct in ('global', 'root_repos'): | |
|
129 | return cstruct | |
|
151 | return { | |
|
152 | 'repo': None, | |
|
153 | 'repo_group': repo_group, | |
|
154 | 'child_repos_only': True | |
|
155 | } | |
|
156 | elif cstruct == 'global': | |
|
157 | return { | |
|
158 | 'repo': None, | |
|
159 | 'repo_group': None, | |
|
160 | 'child_repos_only': False | |
|
161 | } | |
|
162 | elif cstruct == 'root-repos': | |
|
163 | return { | |
|
164 | 'repo': None, | |
|
165 | 'repo_group': None, | |
|
166 | 'child_repos_only': True | |
|
167 | } | |
|
130 | 168 | |
|
131 | 169 | raise colander.Invalid(node, '%r is not a valid scope' % cstruct) |
|
132 | 170 | |
|
171 | ||
|
133 | 172 | class IntegrationOptionsSchemaBase(colander.MappingSchema): |
|
134 | 173 | |
|
135 | 174 | name = colander.SchemaNode( |
@@ -140,10 +179,10 b' class IntegrationOptionsSchemaBase(colan' | |||
|
140 | 179 | ) |
|
141 | 180 | |
|
142 | 181 | scope = colander.SchemaNode( |
|
143 | IntegrationScope(), | |
|
182 | IntegrationScopeType(), | |
|
144 | 183 | description=_( |
|
145 |
'Scope of the integration. |
|
|
146 |
' runs on all |
|
|
184 | 'Scope of the integration. Recursive means the integration ' | |
|
185 | ' runs on all repos of that group and children recursively.'), | |
|
147 | 186 | title=_('Integration scope'), |
|
148 | 187 | validator=deferred_integration_scopes_validator, |
|
149 | 188 | widget=deferred_integration_scopes_widget, |
@@ -166,14 +166,17 b'' | |||
|
166 | 166 | %elif integration.repo_group: |
|
167 | 167 | <a href="${h.url('repo_group_home', group_name=integration.repo_group.group_name)}"> |
|
168 | 168 | ${_('repogroup')}:${integration.repo_group.group_name} |
|
169 | %if integration.child_repos_only: | |
|
170 | ${_('child repos only')} | |
|
171 | %else: | |
|
172 | ${_('cascade to all')} | |
|
173 | %endif | |
|
169 | 174 | </a> |
|
170 | 175 | %else: |
|
171 |
%if integration. |
|
|
176 | %if integration.child_repos_only: | |
|
172 | 177 | ${_('top level repos only')} |
|
173 | %elif integration.scope == 'global': | |
|
178 | %else: | |
|
174 | 179 | ${_('global')} |
|
175 | %else: | |
|
176 | ${_('unknown scope')}: ${integration.scope} | |
|
177 | 180 | %endif |
|
178 | 181 | </td> |
|
179 | 182 | %endif |
@@ -222,12 +222,14 b' def _post_integration_test_helper(app, u' | |||
|
222 | 222 | scopes_destinations = [ |
|
223 | 223 | ('global', |
|
224 | 224 | ADMIN_PREFIX + '/integrations'), |
|
225 |
('root |
|
|
225 | ('root-repos', | |
|
226 | 226 | ADMIN_PREFIX + '/integrations'), |
|
227 | 227 | ('repo:%s' % repo.repo_name, |
|
228 | 228 | '/%s/settings/integrations' % repo.repo_name), |
|
229 | 229 | ('repogroup:%s' % repo_group.group_name, |
|
230 | 230 | '/%s/settings/integrations' % repo_group.group_name), |
|
231 | ('repogroup-recursive:%s' % repo_group.group_name, | |
|
232 | '/%s/settings/integrations' % repo_group.group_name), | |
|
231 | 233 | ] |
|
232 | 234 | |
|
233 | 235 | for scope, destination in scopes_destinations: |
@@ -51,75 +51,84 b' class TestDeleteScopesDeletesIntegration' | |||
|
51 | 51 | def integration_repos(request, StubIntegrationType, stub_integration_settings): |
|
52 | 52 | """ |
|
53 | 53 | Create repositories and integrations for testing, and destroy them after |
|
54 | ||
|
55 | Structure: | |
|
56 | root_repo | |
|
57 | parent_group/ | |
|
58 | parent_repo | |
|
59 | child_group/ | |
|
60 | child_repo | |
|
61 | other_group/ | |
|
62 | other_repo | |
|
54 | 63 | """ |
|
55 | 64 | fixture = Fixture() |
|
56 | 65 | |
|
57 | repo_group_1_id = 'int_test_repo_group_1_%s' % time.time() | |
|
58 | repo_group_1 = fixture.create_repo_group(repo_group_1_id) | |
|
59 | repo_group_2_id = 'int_test_repo_group_2_%s' % time.time() | |
|
60 | repo_group_2 = fixture.create_repo_group(repo_group_2_id) | |
|
66 | ||
|
67 | parent_group_id = 'int_test_parent_group_%s' % time.time() | |
|
68 | parent_group = fixture.create_repo_group(parent_group_id) | |
|
69 | ||
|
70 | other_group_id = 'int_test_other_group_%s' % time.time() | |
|
71 | other_group = fixture.create_repo_group(other_group_id) | |
|
61 | 72 | |
|
62 | repo_1_id = 'int_test_repo_1_%s' % time.time() | |
|
63 | repo_1 = fixture.create_repo(repo_1_id, repo_group=repo_group_1) | |
|
64 | repo_2_id = 'int_test_repo_2_%s' % time.time() | |
|
65 | repo_2 = fixture.create_repo(repo_2_id, repo_group=repo_group_2) | |
|
73 | child_group_id = ( | |
|
74 | parent_group_id + '/' + 'int_test_child_group_%s' % time.time()) | |
|
75 | child_group = fixture.create_repo_group(child_group_id) | |
|
76 | ||
|
77 | parent_repo_id = 'int_test_parent_repo_%s' % time.time() | |
|
78 | parent_repo = fixture.create_repo(parent_repo_id, repo_group=parent_group) | |
|
79 | ||
|
80 | child_repo_id = 'int_test_child_repo_%s' % time.time() | |
|
81 | child_repo = fixture.create_repo(child_repo_id, repo_group=child_group) | |
|
82 | ||
|
83 | other_repo_id = 'int_test_other_repo_%s' % time.time() | |
|
84 | other_repo = fixture.create_repo(other_repo_id, repo_group=other_group) | |
|
66 | 85 | |
|
67 | 86 | root_repo_id = 'int_test_repo_root_%s' % time.time() |
|
68 | 87 | root_repo = fixture.create_repo(root_repo_id) |
|
69 | 88 | |
|
70 | integration_global = IntegrationModel().create( | |
|
71 | StubIntegrationType, settings=stub_integration_settings, | |
|
72 | enabled=True, name='test global integration', scope='global') | |
|
73 | integration_root_repos = IntegrationModel().create( | |
|
74 | StubIntegrationType, settings=stub_integration_settings, | |
|
75 | enabled=True, name='test root repos integration', scope='root_repos') | |
|
76 | integration_repo_1 = IntegrationModel().create( | |
|
77 | StubIntegrationType, settings=stub_integration_settings, | |
|
78 | enabled=True, name='test repo 1 integration', scope=repo_1) | |
|
79 | integration_repo_group_1 = IntegrationModel().create( | |
|
80 | StubIntegrationType, settings=stub_integration_settings, | |
|
81 | enabled=True, name='test repo group 1 integration', scope=repo_group_1) | |
|
82 | integration_repo_2 = IntegrationModel().create( | |
|
83 | StubIntegrationType, settings=stub_integration_settings, | |
|
84 | enabled=True, name='test repo 2 integration', scope=repo_2) | |
|
85 |
integration |
|
|
86 | StubIntegrationType, settings=stub_integration_settings, | |
|
87 |
enabled=True, name='test |
|
|
89 | integrations = {} | |
|
90 | for name, repo, repo_group, child_repos_only in [ | |
|
91 | ('global', None, None, None), | |
|
92 | ('root_repos', None, None, True), | |
|
93 | ('parent_repo', parent_repo, None, None), | |
|
94 | ('child_repo', child_repo, None, None), | |
|
95 | ('other_repo', other_repo, None, None), | |
|
96 | ('root_repo', root_repo, None, None), | |
|
97 | ('parent_group', None, parent_group, True), | |
|
98 | ('parent_group_recursive', None, parent_group, False), | |
|
99 | ('child_group', None, child_group, True), | |
|
100 | ('child_group_recursive', None, child_group, False), | |
|
101 | ('other_group', None, other_group, True), | |
|
102 | ('other_group_recursive', None, other_group, False), | |
|
103 | ]: | |
|
104 | integrations[name] = IntegrationModel().create( | |
|
105 | StubIntegrationType, settings=stub_integration_settings, | |
|
106 | enabled=True, name='test %s integration' % name, | |
|
107 | repo=repo, repo_group=repo_group, child_repos_only=child_repos_only) | |
|
88 | 108 | |
|
89 | 109 | Session().commit() |
|
90 | 110 | |
|
91 | 111 | def _cleanup(): |
|
92 | Session().delete(integration_global) | |
|
93 |
Session |
|
|
94 | Session().delete(integration_repo_1) | |
|
95 | Session().delete(integration_repo_group_1) | |
|
96 | Session().delete(integration_repo_2) | |
|
97 | Session().delete(integration_repo_group_2) | |
|
112 | for integration in integrations.values(): | |
|
113 | Session.delete(integration) | |
|
114 | ||
|
98 | 115 | fixture.destroy_repo(root_repo) |
|
99 |
fixture.destroy_repo(repo |
|
|
100 |
fixture.destroy_repo(repo |
|
|
101 |
fixture.destroy_repo |
|
|
102 |
fixture.destroy_repo_group( |
|
|
116 | fixture.destroy_repo(child_repo) | |
|
117 | fixture.destroy_repo(parent_repo) | |
|
118 | fixture.destroy_repo(other_repo) | |
|
119 | fixture.destroy_repo_group(child_group) | |
|
120 | fixture.destroy_repo_group(parent_group) | |
|
121 | fixture.destroy_repo_group(other_group) | |
|
103 | 122 | |
|
104 | 123 | request.addfinalizer(_cleanup) |
|
105 | 124 | |
|
106 | 125 | return { |
|
126 | 'integrations': integrations, | |
|
107 | 127 | 'repos': { |
|
108 | 'repo_1': repo_1, | |
|
109 | 'repo_2': repo_2, | |
|
110 | 128 | 'root_repo': root_repo, |
|
111 | }, | |
|
112 | 'repo_groups': { | |
|
113 |
'repo |
|
|
114 | 'repo_group_2': repo_group_2, | |
|
115 | }, | |
|
116 | 'integrations': { | |
|
117 | 'global': integration_global, | |
|
118 | 'root_repos': integration_root_repos, | |
|
119 | 'repo_1': integration_repo_1, | |
|
120 | 'repo_2': integration_repo_2, | |
|
121 | 'repo_group_1': integration_repo_group_1, | |
|
122 | 'repo_group_2': integration_repo_group_2, | |
|
129 | 'other_repo': other_repo, | |
|
130 | 'parent_repo': parent_repo, | |
|
131 | 'child_repo': child_repo, | |
|
123 | 132 | } |
|
124 | 133 | } |
|
125 | 134 | |
@@ -133,27 +142,41 b' def test_enabled_integration_repo_scopes' | |||
|
133 | 142 | |
|
134 | 143 | assert triggered_integrations == [ |
|
135 | 144 | integrations['global'], |
|
136 | integrations['root_repos'] | |
|
145 | integrations['root_repos'], | |
|
146 | integrations['root_repo'], | |
|
147 | ] | |
|
148 | ||
|
149 | ||
|
150 | triggered_integrations = IntegrationModel().get_for_event( | |
|
151 | events.RepoEvent(repos['other_repo'])) | |
|
152 | ||
|
153 | assert triggered_integrations == [ | |
|
154 | integrations['global'], | |
|
155 | integrations['other_repo'], | |
|
156 | integrations['other_group'], | |
|
157 | integrations['other_group_recursive'], | |
|
137 | 158 | ] |
|
138 | 159 | |
|
139 | 160 | |
|
140 | 161 | triggered_integrations = IntegrationModel().get_for_event( |
|
141 |
events.RepoEvent(repos['repo |
|
|
162 | events.RepoEvent(repos['parent_repo'])) | |
|
142 | 163 | |
|
143 | 164 | assert triggered_integrations == [ |
|
144 | 165 | integrations['global'], |
|
145 |
integrations['repo |
|
|
146 |
integrations[' |
|
|
166 | integrations['parent_repo'], | |
|
167 | integrations['parent_group'], | |
|
168 | integrations['parent_group_recursive'], | |
|
147 | 169 | ] |
|
148 | 170 | |
|
149 | ||
|
150 | 171 | triggered_integrations = IntegrationModel().get_for_event( |
|
151 |
events.RepoEvent(repos['repo |
|
|
172 | events.RepoEvent(repos['child_repo'])) | |
|
152 | 173 | |
|
153 | 174 | assert triggered_integrations == [ |
|
154 | 175 | integrations['global'], |
|
155 |
integrations['repo |
|
|
156 |
integrations[' |
|
|
176 | integrations['child_repo'], | |
|
177 | integrations['parent_group_recursive'], | |
|
178 | integrations['child_group'], | |
|
179 | integrations['child_group_recursive'], | |
|
157 | 180 | ] |
|
158 | 181 | |
|
159 | 182 | |
@@ -172,17 +195,24 b' def test_disabled_integration_repo_scope' | |||
|
172 | 195 | |
|
173 | 196 | |
|
174 | 197 | triggered_integrations = IntegrationModel().get_for_event( |
|
175 |
events.RepoEvent(repos['repo |
|
|
198 | events.RepoEvent(repos['parent_repo'])) | |
|
176 | 199 | |
|
177 | 200 | assert triggered_integrations == [] |
|
178 | 201 | |
|
179 | 202 | |
|
180 | 203 | triggered_integrations = IntegrationModel().get_for_event( |
|
181 |
events.RepoEvent(repos['repo |
|
|
204 | events.RepoEvent(repos['child_repo'])) | |
|
182 | 205 | |
|
183 | 206 | assert triggered_integrations == [] |
|
184 | 207 | |
|
185 | 208 | |
|
209 | triggered_integrations = IntegrationModel().get_for_event( | |
|
210 | events.RepoEvent(repos['other_repo'])) | |
|
211 | ||
|
212 | assert triggered_integrations == [] | |
|
213 | ||
|
214 | ||
|
215 | ||
|
186 | 216 | def test_enabled_non_repo_integrations(integration_repos): |
|
187 | 217 | integrations = integration_repos['integrations'] |
|
188 | 218 |
@@ -47,42 +47,93 b' class TestIntegrationSchema(object):' | |||
|
47 | 47 | 'repositories_groups': {}, |
|
48 | 48 | } |
|
49 | 49 | |
|
50 |
perms_tests = |
|
|
51 | ('repo:%s' % repo.repo_name, repo): [ | |
|
52 | ({}, False), | |
|
53 | ({'global': ['hg.admin']}, True), | |
|
54 | ({'global': []}, False), | |
|
55 | ({'repositories': {repo.repo_name: 'repository.admin'}}, True), | |
|
56 | ({'repositories': {repo.repo_name: 'repository.read'}}, False), | |
|
57 | ({'repositories': {repo.repo_name: 'repository.write'}}, False), | |
|
58 | ({'repositories': {repo.repo_name: 'repository.none'}}, False), | |
|
59 | ], | |
|
60 | ('repogroup:%s' % repo_group.group_name, repo_group): [ | |
|
61 | ({}, False), | |
|
62 |
({' |
|
|
63 | ({'global': []}, False), | |
|
64 | ({'repositories_groups': | |
|
65 |
{ |
|
|
66 | ({'repositories_groups': | |
|
67 | {repo_group.group_name: 'group.read'}}, False), | |
|
68 | ({'repositories_groups': | |
|
69 |
|
|
|
70 | ({'repositories_groups': | |
|
71 |
|
|
|
72 | ], | |
|
73 | ('global', 'global'): [ | |
|
74 |
|
|
|
75 | ({'global': ['hg.admin']}, True), | |
|
76 |
({ |
|
|
77 | ], | |
|
78 | ('root_repos', 'root_repos'): [ | |
|
79 | ({}, False), | |
|
80 | ({'global': ['hg.admin']}, True), | |
|
81 | ({'global': []}, False), | |
|
82 | ], | |
|
83 | } | |
|
50 | perms_tests = [ | |
|
51 | ( | |
|
52 | 'repo:%s' % repo.repo_name, | |
|
53 | { | |
|
54 | 'child_repos_only': None, | |
|
55 | 'repo_group': None, | |
|
56 | 'repo': repo, | |
|
57 | }, | |
|
58 | [ | |
|
59 | ({}, False), | |
|
60 | ({'global': ['hg.admin']}, True), | |
|
61 | ({'global': []}, False), | |
|
62 | ({'repositories': {repo.repo_name: 'repository.admin'}}, True), | |
|
63 | ({'repositories': {repo.repo_name: 'repository.read'}}, False), | |
|
64 | ({'repositories': {repo.repo_name: 'repository.write'}}, False), | |
|
65 | ({'repositories': {repo.repo_name: 'repository.none'}}, False), | |
|
66 | ] | |
|
67 | ), | |
|
68 | ( | |
|
69 | 'repogroup:%s' % repo_group.group_name, | |
|
70 | { | |
|
71 | 'repo': None, | |
|
72 | 'repo_group': repo_group, | |
|
73 | 'child_repos_only': True, | |
|
74 | }, | |
|
75 | [ | |
|
76 | ({}, False), | |
|
77 | ({'global': ['hg.admin']}, True), | |
|
78 | ({'global': []}, False), | |
|
79 | ({'repositories_groups': | |
|
80 | {repo_group.group_name: 'group.admin'}}, True), | |
|
81 | ({'repositories_groups': | |
|
82 | {repo_group.group_name: 'group.read'}}, False), | |
|
83 | ({'repositories_groups': | |
|
84 | {repo_group.group_name: 'group.write'}}, False), | |
|
85 | ({'repositories_groups': | |
|
86 | {repo_group.group_name: 'group.none'}}, False), | |
|
87 | ] | |
|
88 | ), | |
|
89 | ( | |
|
90 | 'repogroup-recursive:%s' % repo_group.group_name, | |
|
91 | { | |
|
92 | 'repo': None, | |
|
93 | 'repo_group': repo_group, | |
|
94 | 'child_repos_only': False, | |
|
95 | }, | |
|
96 | [ | |
|
97 | ({}, False), | |
|
98 | ({'global': ['hg.admin']}, True), | |
|
99 | ({'global': []}, False), | |
|
100 | ({'repositories_groups': | |
|
101 | {repo_group.group_name: 'group.admin'}}, True), | |
|
102 | ({'repositories_groups': | |
|
103 | {repo_group.group_name: 'group.read'}}, False), | |
|
104 | ({'repositories_groups': | |
|
105 | {repo_group.group_name: 'group.write'}}, False), | |
|
106 | ({'repositories_groups': | |
|
107 | {repo_group.group_name: 'group.none'}}, False), | |
|
108 | ] | |
|
109 | ), | |
|
110 | ( | |
|
111 | 'global', | |
|
112 | { | |
|
113 | 'repo': None, | |
|
114 | 'repo_group': None, | |
|
115 | 'child_repos_only': False, | |
|
116 | }, [ | |
|
117 | ({}, False), | |
|
118 | ({'global': ['hg.admin']}, True), | |
|
119 | ({'global': []}, False), | |
|
120 | ] | |
|
121 | ), | |
|
122 | ( | |
|
123 | 'root-repos', | |
|
124 | { | |
|
125 | 'repo': None, | |
|
126 | 'repo_group': None, | |
|
127 | 'child_repos_only': True, | |
|
128 | }, [ | |
|
129 | ({}, False), | |
|
130 | ({'global': ['hg.admin']}, True), | |
|
131 | ({'global': []}, False), | |
|
132 | ] | |
|
133 | ), | |
|
134 | ] | |
|
84 | 135 | |
|
85 |
for |
|
|
136 | for scope_input, scope_output, perms_allowed in perms_tests: | |
|
86 | 137 | for perms_update, allowed in perms_allowed: |
|
87 | 138 | perms = dict(empty_perms_dict, **perms_update) |
|
88 | 139 |
@@ -1709,7 +1709,8 b' def repo_integration_stub(request, repo_' | |||
|
1709 | 1709 | stub_integration_settings): |
|
1710 | 1710 | integration = IntegrationModel().create( |
|
1711 | 1711 | StubIntegrationType, settings=stub_integration_settings, enabled=True, |
|
1712 |
name='test repo integration', |
|
|
1712 | name='test repo integration', | |
|
1713 | repo=repo_stub, repo_group=None, child_repos_only=None) | |
|
1713 | 1714 | |
|
1714 | 1715 | @request.addfinalizer |
|
1715 | 1716 | def cleanup(): |
@@ -1723,7 +1724,23 b' def repogroup_integration_stub(request, ' | |||
|
1723 | 1724 | stub_integration_settings): |
|
1724 | 1725 | integration = IntegrationModel().create( |
|
1725 | 1726 | StubIntegrationType, settings=stub_integration_settings, enabled=True, |
|
1726 |
name='test repogroup integration', |
|
|
1727 | name='test repogroup integration', | |
|
1728 | repo=None, repo_group=test_repo_group, child_repos_only=True) | |
|
1729 | ||
|
1730 | @request.addfinalizer | |
|
1731 | def cleanup(): | |
|
1732 | IntegrationModel().delete(integration) | |
|
1733 | ||
|
1734 | return integration | |
|
1735 | ||
|
1736 | ||
|
1737 | @pytest.fixture | |
|
1738 | def repogroup_recursive_integration_stub(request, test_repo_group, | |
|
1739 | StubIntegrationType, stub_integration_settings): | |
|
1740 | integration = IntegrationModel().create( | |
|
1741 | StubIntegrationType, settings=stub_integration_settings, enabled=True, | |
|
1742 | name='test recursive repogroup integration', | |
|
1743 | repo=None, repo_group=test_repo_group, child_repos_only=False) | |
|
1727 | 1744 | |
|
1728 | 1745 | @request.addfinalizer |
|
1729 | 1746 | def cleanup(): |
@@ -1737,7 +1754,8 b' def global_integration_stub(request, Stu' | |||
|
1737 | 1754 | stub_integration_settings): |
|
1738 | 1755 | integration = IntegrationModel().create( |
|
1739 | 1756 | StubIntegrationType, settings=stub_integration_settings, enabled=True, |
|
1740 |
name='test global integration', |
|
|
1757 | name='test global integration', | |
|
1758 | repo=None, repo_group=None, child_repos_only=None) | |
|
1741 | 1759 | |
|
1742 | 1760 | @request.addfinalizer |
|
1743 | 1761 | def cleanup(): |
@@ -1751,7 +1769,8 b' def root_repos_integration_stub(request,' | |||
|
1751 | 1769 | stub_integration_settings): |
|
1752 | 1770 | integration = IntegrationModel().create( |
|
1753 | 1771 | StubIntegrationType, settings=stub_integration_settings, enabled=True, |
|
1754 |
name='test global integration', |
|
|
1772 | name='test global integration', | |
|
1773 | repo=None, repo_group=None, child_repos_only=True) | |
|
1755 | 1774 | |
|
1756 | 1775 | @request.addfinalizer |
|
1757 | 1776 | def cleanup(): |
General Comments 0
You need to be logged in to leave comments.
Login now