Add repository-specific non-ff disallowed option (#1579)

Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
Florian Scholdei
2021-03-11 10:13:26 +01:00
committed by GitHub
parent 831877564d
commit 0d3339b0cb
18 changed files with 142 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -11,6 +11,9 @@ Unter dem Eintrag "Generell" kann man die Zusatzinformationen zum Repository edi
Git Repository handelt, kann ebenfalls der Standard-Branch für dieses Repository gesetzt werden. Der Standard-Branch Git Repository handelt, kann ebenfalls der Standard-Branch für dieses Repository gesetzt werden. Der Standard-Branch
sorgt dafür, dass beim Arbeiten mit diesem Repository dieser Branch vorrangig geöffnet wird, falls kein expliziter sorgt dafür, dass beim Arbeiten mit diesem Repository dieser Branch vorrangig geöffnet wird, falls kein expliziter
Branch ausgewählt wurde. Branch ausgewählt wurde.
Außerdem können Git Pushes auf Repository-Ebene abgelehnt werden, die nicht "fast-forward" sind.
![Repository-Settings-General-Git](assets/repository-settings-general-git.png)
Innerhalb der Gefahrenzone unten auf der Seite gibt es mit entsprechenden Rechten die Möglichkeit das Repository Innerhalb der Gefahrenzone unten auf der Seite gibt es mit entsprechenden Rechten die Möglichkeit das Repository
umzubenennen, zu löschen oder als archiviert zu markieren. Wenn in der globalen SCM-Manager Konfiguration die Namespace umzubenennen, zu löschen oder als archiviert zu markieren. Wenn in der globalen SCM-Manager Konfiguration die Namespace

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -10,6 +10,9 @@ can be considerably more items.
The "General" item allows you to edit the additional information of the repository. Git repositories for example also The "General" item allows you to edit the additional information of the repository. Git repositories for example also
have the option to change the default branch here. The default branch is the one that is used when working with the have the option to change the default branch here. The default branch is the one that is used when working with the
repository if no specific branch is selected. repository if no specific branch is selected.
In addition, Git pushes which are non fast-forward can be rejected at the repository level.
![Repository-Settings-General-Git](assets/repository-settings-general-git.png)
In the danger zone at the bottom you may rename the repository, delete it or mark it as archived. If the namespace In the danger zone at the bottom you may rename the repository, delete it or mark it as archived. If the namespace
strategy in the global SCM-Manager config is set to `custom` you may even rename the repository namespace. If a strategy in the global SCM-Manager config is set to `custom` you may even rename the repository namespace. If a

View File

@@ -0,0 +1,2 @@
- type: added
description: Add repository-specific non-fast-forward disallowed option ([#1579](https://github.com/scm-manager/scm-manager/issues/1579))

View File

@@ -40,6 +40,8 @@ public class GitRepositoryConfigDto extends HalRepresentation implements UpdateG
private String defaultBranch; private String defaultBranch;
private boolean nonFastForwardDisallowed;
@Override @Override
@SuppressWarnings("squid:S1185") // We want to have this method available in this package @SuppressWarnings("squid:S1185") // We want to have this method available in this package
protected HalRepresentation add(Links links) { protected HalRepresentation add(Links links) {

View File

@@ -119,7 +119,7 @@ public class GitRepositoryConfigResource {
schema = @Schema(implementation = UpdateGitRepositoryConfigDto.class), schema = @Schema(implementation = UpdateGitRepositoryConfigDto.class),
examples = @ExampleObject( examples = @ExampleObject(
name = "Overwrites current configuration with this one.", name = "Overwrites current configuration with this one.",
value = "{\n \"defaultBranch\":\"main\"\n}", value = "{\n \"defaultBranch\":\"main\"\n \"nonFastForwardDisallowed\":false,\n}",
summary = "Simple update configuration" summary = "Simple update configuration"
) )
) )

View File

@@ -42,7 +42,22 @@ public class GitRepositoryConfigStoreProvider {
} }
public ConfigurationStore<GitRepositoryConfig> get(Repository repository) { public ConfigurationStore<GitRepositoryConfig> get(Repository repository) {
return new StoreWrapper(configurationStoreFactory.withType(GitRepositoryConfig.class).withName("gitConfig").forRepository(repository).build(), repository); return new StoreWrapper(createStore(repository.getId()), repository);
}
public GitRepositoryConfig getGitRepositoryConfig(String repositoryId) {
return getFronStore(createStore(repositoryId));
}
private static GitRepositoryConfig getFronStore(ConfigurationStore<GitRepositoryConfig> store) {
return store.getOptional().orElse(new GitRepositoryConfig());
}
private ConfigurationStore<GitRepositoryConfig> createStore(String id) {
return configurationStoreFactory
.withType(GitRepositoryConfig.class)
.withName("gitConfig")
.forRepository(id).build();
} }
private static class StoreWrapper implements ConfigurationStore<GitRepositoryConfig> { private static class StoreWrapper implements ConfigurationStore<GitRepositoryConfig> {
@@ -57,11 +72,7 @@ public class GitRepositoryConfigStoreProvider {
@Override @Override
public GitRepositoryConfig get() { public GitRepositoryConfig get() {
GitRepositoryConfig config = delegate.get(); return getFronStore(delegate);
if (config == null) {
return new GitRepositoryConfig();
}
return config;
} }
@Override @Override

View File

@@ -26,4 +26,5 @@ package sonia.scm.api.v2.resources;
interface UpdateGitRepositoryConfigDto { interface UpdateGitRepositoryConfigDto {
String getDefaultBranch(); String getDefaultBranch();
boolean isNonFastForwardDisallowed();
} }

View File

@@ -29,7 +29,9 @@ import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.repository.GitChangesetConverterFactory; import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryConfig;
import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.web.CollectingPackParserListener; import sonia.scm.web.CollectingPackParserListener;
import sonia.scm.web.GitHookEventFacade; import sonia.scm.web.GitHookEventFacade;
@@ -39,16 +41,21 @@ public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T>
private final GitRepositoryHandler handler; private final GitRepositoryHandler handler;
private final GitReceiveHook hook; private final GitReceiveHook hook;
private final GitRepositoryConfigStoreProvider storeProvider;
protected BaseReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) { protected BaseReceivePackFactory(GitChangesetConverterFactory converterFactory,
GitRepositoryHandler handler,
GitHookEventFacade hookEventFacade,
GitRepositoryConfigStoreProvider storeProvider) {
this.handler = handler; this.handler = handler;
this.storeProvider = storeProvider;
this.hook = new GitReceiveHook(converterFactory, hookEventFacade, handler); this.hook = new GitReceiveHook(converterFactory, hookEventFacade, handler);
} }
@Override @Override
public final ReceivePack create(T connection, Repository repository) throws ServiceNotAuthorizedException, ServiceNotEnabledException { public final ReceivePack create(T connection, Repository repository) throws ServiceNotAuthorizedException, ServiceNotEnabledException {
ReceivePack receivePack = createBasicReceivePack(connection, repository); ReceivePack receivePack = createBasicReceivePack(connection, repository);
receivePack.setAllowNonFastForwards(isNonFastForwardAllowed()); receivePack.setAllowNonFastForwards(isNonFastForwardAllowed(repository));
receivePack.setPreReceiveHook(hook); receivePack.setPreReceiveHook(hook);
receivePack.setPostReceiveHook(hook); receivePack.setPostReceiveHook(hook);
@@ -61,7 +68,9 @@ public abstract class BaseReceivePackFactory<T> implements ReceivePackFactory<T>
protected abstract ReceivePack createBasicReceivePack(T request, Repository repository) protected abstract ReceivePack createBasicReceivePack(T request, Repository repository)
throws ServiceNotEnabledException, ServiceNotAuthorizedException; throws ServiceNotEnabledException, ServiceNotAuthorizedException;
private boolean isNonFastForwardAllowed() { private boolean isNonFastForwardAllowed(Repository repository) {
return ! handler.getConfig().isNonFastForwardDisallowed(); String repositoryId = handler.getRepositoryId(repository.getConfig());
GitRepositoryConfig gitRepositoryConfig = storeProvider.getGitRepositoryConfig(repositoryId);
return !(handler.getConfig().isNonFastForwardDisallowed() || gitRepositoryConfig.isNonFastForwardDisallowed());
} }
} }

View File

@@ -27,6 +27,7 @@ package sonia.scm.protocolcommand.git;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.ReceivePack;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.protocolcommand.RepositoryContext; import sonia.scm.protocolcommand.RepositoryContext;
import sonia.scm.repository.GitChangesetConverterFactory; import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.GitRepositoryHandler;
@@ -35,8 +36,11 @@ import sonia.scm.web.GitHookEventFacade;
public class ScmReceivePackFactory extends BaseReceivePackFactory<RepositoryContext> { public class ScmReceivePackFactory extends BaseReceivePackFactory<RepositoryContext> {
@Inject @Inject
public ScmReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) { public ScmReceivePackFactory(GitChangesetConverterFactory converterFactory,
super(converterFactory, handler, hookEventFacade); GitRepositoryHandler handler,
GitHookEventFacade hookEventFacade,
GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider) {
super(converterFactory, handler, hookEventFacade, gitRepositoryConfigStoreProvider);
} }
@Override @Override

View File

@@ -40,6 +40,7 @@ public class GitRepositoryConfig {
} }
private String defaultBranch; private String defaultBranch;
private boolean nonFastForwardDisallowed;
public String getDefaultBranch() { public String getDefaultBranch() {
return defaultBranch; return defaultBranch;
@@ -48,4 +49,10 @@ public class GitRepositoryConfig {
public void setDefaultBranch(String defaultBranch) { public void setDefaultBranch(String defaultBranch) {
this.defaultBranch = defaultBranch; this.defaultBranch = defaultBranch;
} }
public boolean isNonFastForwardDisallowed() { return nonFastForwardDisallowed; }
public void setNonFastForwardDisallowed(boolean nonFastForwardDisallowed) {
this.nonFastForwardDisallowed = nonFastForwardDisallowed;
}
} }

View File

@@ -33,6 +33,7 @@ import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.protocolcommand.git.BaseReceivePackFactory; import sonia.scm.protocolcommand.git.BaseReceivePackFactory;
import sonia.scm.repository.GitChangesetConverterFactory; import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.GitRepositoryHandler;
@@ -53,8 +54,11 @@ public class GitReceivePackFactory extends BaseReceivePackFactory<HttpServletReq
private ReceivePackFactory<HttpServletRequest> wrapped; private ReceivePackFactory<HttpServletRequest> wrapped;
@Inject @Inject
public GitReceivePackFactory(GitChangesetConverterFactory converterFactory, GitRepositoryHandler handler, GitHookEventFacade hookEventFacade) { public GitReceivePackFactory(GitChangesetConverterFactory converterFactory,
super(converterFactory, handler, hookEventFacade); GitRepositoryHandler handler,
GitHookEventFacade hookEventFacade,
GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider) {
super(converterFactory, handler, hookEventFacade, gitRepositoryConfigStoreProvider);
this.wrapped = new DefaultReceivePackFactory(); this.wrapped = new DefaultReceivePackFactory();
} }

View File

@@ -27,6 +27,7 @@ import { Branch, Repository, Link } from "@scm-manager/ui-types";
import { import {
apiClient, apiClient,
BranchSelector, BranchSelector,
Checkbox,
ErrorPage, ErrorPage,
Loading, Loading,
Subtitle, Subtitle,
@@ -45,8 +46,10 @@ type State = {
error?: Error; error?: Error;
branches: Branch[]; branches: Branch[];
selectedBranchName: string; selectedBranchName: string;
defaultBranchChanged: boolean; nonFastForwardDisallowed: boolean;
changesSubmitted: boolean;
disabled: boolean; disabled: boolean;
changed: boolean;
}; };
const GIT_CONFIG_CONTENT_TYPE = "application/vnd.scmm-gitConfig+json"; const GIT_CONFIG_CONTENT_TYPE = "application/vnd.scmm-gitConfig+json";
@@ -61,15 +64,16 @@ class RepositoryConfig extends React.Component<Props, State> {
submitPending: false, submitPending: false,
branches: [], branches: [],
selectedBranchName: "", selectedBranchName: "",
defaultBranchChanged: false, nonFastForwardDisallowed: false,
disabled: true changesSubmitted: false,
disabled: true,
changed: false
}; };
} }
componentDidMount() { componentDidMount() {
const { repository } = this.props; const { repository } = this.props;
this.setState({ this.setState({
...this.state,
loadingBranches: true loadingBranches: true
}); });
const branchesLink = repository._links.branches as Link; const branchesLink = repository._links.branches as Link;
@@ -79,21 +83,18 @@ class RepositoryConfig extends React.Component<Props, State> {
.then(payload => payload._embedded.branches) .then(payload => payload._embedded.branches)
.then(branches => .then(branches =>
this.setState({ this.setState({
...this.state,
branches, branches,
loadingBranches: false loadingBranches: false
}) })
) )
.catch(error => .catch(error =>
this.setState({ this.setState({
...this.state,
error error
}) })
); );
const configurationLink = repository._links.configuration as Link; const configurationLink = repository._links.configuration as Link;
this.setState({ this.setState({
...this.state,
loadingDefaultBranch: true loadingDefaultBranch: true
}); });
apiClient apiClient
@@ -101,15 +102,15 @@ class RepositoryConfig extends React.Component<Props, State> {
.then(response => response.json()) .then(response => response.json())
.then(payload => .then(payload =>
this.setState({ this.setState({
...this.state,
selectedBranchName: payload.defaultBranch, selectedBranchName: payload.defaultBranch,
nonFastForwardDisallowed: payload.nonFastForwardDisallowed,
disabled: !payload._links.update, disabled: !payload._links.update,
loadingDefaultBranch: false loadingDefaultBranch: false,
changed: false
}) })
) )
.catch(error => .catch(error =>
this.setState({ this.setState({
...this.state,
error error
}) })
); );
@@ -118,28 +119,36 @@ class RepositoryConfig extends React.Component<Props, State> {
branchSelected = (branch?: Branch) => { branchSelected = (branch?: Branch) => {
if (!branch) { if (!branch) {
this.setState({ this.setState({
...this.state,
selectedBranchName: "", selectedBranchName: "",
defaultBranchChanged: false changesSubmitted: false,
changed: true
}); });
} else { } else {
this.setState({ this.setState({
...this.state,
selectedBranchName: branch.name, selectedBranchName: branch.name,
defaultBranchChanged: false changesSubmitted: false,
changed: true
}); });
} }
}; };
onNonFastForwardDisallowed = (value: boolean) => {
this.setState({
nonFastForwardDisallowed: value,
changed: true
});
};
submit = (event: FormEvent) => { submit = (event: FormEvent) => {
event.preventDefault(); event.preventDefault();
const { repository } = this.props; const { repository } = this.props;
const { selectedBranchName, nonFastForwardDisallowed } = this.state;
const newConfig = { const newConfig = {
defaultBranch: this.state.selectedBranchName defaultBranch: selectedBranchName,
nonFastForwardDisallowed
}; };
this.setState({ this.setState({
...this.state,
submitPending: true submitPending: true
}); });
const configurationLink = repository._links.configuration as Link; const configurationLink = repository._links.configuration as Link;
@@ -147,14 +156,13 @@ class RepositoryConfig extends React.Component<Props, State> {
.put(configurationLink.href, newConfig, GIT_CONFIG_CONTENT_TYPE) .put(configurationLink.href, newConfig, GIT_CONFIG_CONTENT_TYPE)
.then(() => .then(() =>
this.setState({ this.setState({
...this.state,
submitPending: false, submitPending: false,
defaultBranchChanged: true changesSubmitted: true,
changed: false
}) })
) )
.catch(error => .catch(error =>
this.setState({ this.setState({
...this.state,
error error
}) })
); );
@@ -162,13 +170,13 @@ class RepositoryConfig extends React.Component<Props, State> {
render() { render() {
const { t } = this.props; const { t } = this.props;
const { loadingBranches, loadingDefaultBranch, submitPending, error, disabled } = this.state; const { loadingBranches, loadingDefaultBranch, submitPending, error, disabled, changed } = this.state;
if (error) { if (error) {
return ( return (
<ErrorPage <ErrorPage
title={t("scm-git-plugin.repo-config.error.title")} title={t("scm-git-plugin.repoConfig.error.title")}
subtitle={t("scm-git-plugin.repo-config.error.subtitle")} subtitle={t("scm-git-plugin.repoConfig.error.subtitle")}
error={error} error={error}
/> />
); );
@@ -177,27 +185,32 @@ class RepositoryConfig extends React.Component<Props, State> {
const submitButton = disabled ? null : ( const submitButton = disabled ? null : (
<Level <Level
right={ right={
<SubmitButton <SubmitButton label={t("scm-git-plugin.repoConfig.submit")} loading={submitPending} disabled={!changed} />
label={t("scm-git-plugin.repo-config.submit")}
loading={submitPending}
disabled={!this.state.selectedBranchName}
/>
} }
/> />
); );
if (!(loadingBranches || loadingDefaultBranch)) { if (!(loadingBranches || loadingDefaultBranch)) {
const { branches, selectedBranchName, nonFastForwardDisallowed } = this.state;
return ( return (
<> <>
<hr /> <hr />
<Subtitle subtitle={t("scm-git-plugin.repo-config.title")} /> <Subtitle subtitle={t("scm-git-plugin.repoConfig.title")} />
{this.renderBranchChangedNotification()} {this.renderBranchChangedNotification()}
<form onSubmit={this.submit}> <form onSubmit={this.submit}>
<BranchSelector <BranchSelector
label={t("scm-git-plugin.repo-config.default-branch")} label={t("scm-git-plugin.repoConfig.defaultBranch")}
branches={this.state.branches} branches={branches}
onSelectBranch={this.branchSelected} onSelectBranch={this.branchSelected}
selectedBranch={this.state.selectedBranchName} selectedBranch={selectedBranchName}
disabled={disabled}
/>
<Checkbox
name="nonFastForwardDisallowed"
label={t("scm-git-plugin.repoConfig.nonFastForwardDisallowed")}
helpText={t("scm-git-plugin.repoConfig.nonFastForwardDisallowedHelpText")}
checked={nonFastForwardDisallowed}
onChange={this.onNonFastForwardDisallowed}
disabled={disabled} disabled={disabled}
/> />
{submitButton} {submitButton}
@@ -210,19 +223,19 @@ class RepositoryConfig extends React.Component<Props, State> {
} }
renderBranchChangedNotification = () => { renderBranchChangedNotification = () => {
if (this.state.defaultBranchChanged) { if (this.state.changesSubmitted) {
return ( return (
<div className="notification is-primary"> <div className="notification is-primary">
<button <button
className="delete" className="delete"
onClick={() => onClick={() =>
this.setState({ this.setState({
...this.state, changesSubmitted: false,
defaultBranchChanged: false changed: false
}) })
} }
/> />
{this.props.t("scm-git-plugin.repo-config.success")} {this.props.t("scm-git-plugin.repoConfig.success")}
</div> </div>
); );
} }

View File

@@ -31,16 +31,17 @@
"disabledHelpText": "Aktiviere oder deaktiviere das Git Plugin", "disabledHelpText": "Aktiviere oder deaktiviere das Git Plugin",
"submit": "Speichern" "submit": "Speichern"
}, },
"repo-config": { "repoConfig": {
"link": "Konfiguration",
"title": "Git Einstellungen", "title": "Git Einstellungen",
"default-branch": "Standard Branch", "defaultBranch": "Default Branch",
"nonFastForwardDisallowed": "Deaktiviere \"Non Fast-Forward\"",
"nonFastForwardDisallowedHelpText": "Git Pushes ablehnen, die nicht \"fast-forward\" sind, wie \"--force\".",
"submit": "Speichern", "submit": "Speichern",
"error": { "error": {
"title": "Fehler", "title": "Fehler",
"subtitle": "Ein Fehler ist aufgetreten." "subtitle": "Ein Fehler ist aufgetreten."
}, },
"success": "Der standard Branch wurde geändert!" "success": "Einstellungen wurden erfolgreich geändert!"
} }
}, },
"permissions": { "permissions": {

View File

@@ -31,16 +31,17 @@
"disabledHelpText": "Enable or disable the Git plugin", "disabledHelpText": "Enable or disable the Git plugin",
"submit": "Submit" "submit": "Submit"
}, },
"repo-config": { "repoConfig": {
"link": "Configuration",
"title": "Git Settings", "title": "Git Settings",
"default-branch": "Default Branch", "defaultBranch": "Default Branch",
"nonFastForwardDisallowed": "Disallow Non Fast-Forward",
"nonFastForwardDisallowedHelpText": "Reject git pushes which are non fast-forward such as --force.",
"submit": "Submit", "submit": "Submit",
"error": { "error": {
"title": "Error", "title": "Error",
"subtitle": "Something went wrong" "subtitle": "Something went wrong"
}, },
"success": "Default branch changed!" "success": "Configuration changed successfully!"
} }
}, },
"permissions" : { "permissions" : {

View File

@@ -38,7 +38,9 @@ import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.api.v2.resources.GitRepositoryConfigStoreProvider;
import sonia.scm.repository.GitConfig; import sonia.scm.repository.GitConfig;
import sonia.scm.repository.GitRepositoryConfig;
import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.GitTestHelper; import sonia.scm.repository.GitTestHelper;
import sonia.scm.web.CollectingPackParserListener; import sonia.scm.web.CollectingPackParserListener;
@@ -59,17 +61,22 @@ public class BaseReceivePackFactoryTest {
@Mock @Mock
private GitRepositoryHandler handler; private GitRepositoryHandler handler;
private GitConfig config; private GitConfig gitConfig;
@Mock @Mock
private ReceivePackFactory<Object> wrappedReceivePackFactory; private ReceivePackFactory<Object> wrappedReceivePackFactory;
@Mock
private GitRepositoryConfigStoreProvider gitRepositoryConfigStoreProvider;
private BaseReceivePackFactory<Object> factory; private BaseReceivePackFactory<Object> factory;
private Object request = new Object(); private Object request = new Object();
private Repository repository; private Repository repository;
private GitRepositoryConfig gitRepositoryConfig = new GitRepositoryConfig();
@Rule @Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder(); public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -77,13 +84,16 @@ public class BaseReceivePackFactoryTest {
public void setUpObjectUnderTest() throws Exception { public void setUpObjectUnderTest() throws Exception {
this.repository = createRepositoryForTesting(); this.repository = createRepositoryForTesting();
config = new GitConfig(); gitConfig = new GitConfig();
when(handler.getConfig()).thenReturn(config); when(handler.getConfig()).thenReturn(gitConfig);
when(handler.getRepositoryId(repository.getConfig())).thenReturn("heart-of-gold");
ReceivePack receivePack = new ReceivePack(repository); ReceivePack receivePack = new ReceivePack(repository);
when(wrappedReceivePackFactory.create(request, repository)).thenReturn(receivePack); when(wrappedReceivePackFactory.create(request, repository)).thenReturn(receivePack);
factory = new BaseReceivePackFactory<Object>(GitTestHelper.createConverterFactory(), handler, null) { when(gitRepositoryConfigStoreProvider.getGitRepositoryConfig("heart-of-gold")).thenReturn(gitRepositoryConfig);
factory = new BaseReceivePackFactory<Object>(GitTestHelper.createConverterFactory(), handler, null, gitRepositoryConfigStoreProvider) {
@Override @Override
protected ReceivePack createBasicReceivePack(Object request, Repository repository) throws ServiceNotEnabledException, ServiceNotAuthorizedException { protected ReceivePack createBasicReceivePack(Object request, Repository repository) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
return wrappedReceivePackFactory.create(request, repository); return wrappedReceivePackFactory.create(request, repository);
@@ -108,7 +118,14 @@ public class BaseReceivePackFactoryTest {
@Test @Test
public void testCreateWithDisabledNonFastForward() throws Exception { public void testCreateWithDisabledNonFastForward() throws Exception {
config.setNonFastForwardDisallowed(true); gitConfig.setNonFastForwardDisallowed(true);
ReceivePack receivePack = factory.create(request, repository);
assertFalse(receivePack.isAllowNonFastForwards());
}
@Test
public void testCreateWithLocalDisabledNonFastForward() throws Exception {
gitRepositoryConfig.setNonFastForwardDisallowed(true);
ReceivePack receivePack = factory.create(request, repository); ReceivePack receivePack = factory.create(request, repository);
assertFalse(receivePack.isAllowNonFastForwards()); assertFalse(receivePack.isAllowNonFastForwards());
} }