Skip to content

Commit

Permalink
Merge pull request #1 from stefdev49/add_rest_api_tests
Browse files Browse the repository at this point in the history
Add integration tests to test API
  • Loading branch information
stefdev49 authored Jul 24, 2023
2 parents 616bfcc + a774b03 commit 45824b5
Show file tree
Hide file tree
Showing 7 changed files with 574 additions and 90 deletions.
249 changes: 249 additions & 0 deletions docs/REST_CONFIGURATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
# REST CONFIGURATION

You can create, update and delete composer repositories through the rest API.

Setup NEXUS_HOST to the nexus url, for instance in case of a local test instance :
NEXUS_HOST=http://localhost:8081

## Hosted repository

### Create
```shell
curl -X 'POST' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/hosted' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true' \
-d '{
"name": "composer-hosted",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true,
"writePolicy": "allow_once"
},
"cleanup": {
"policyNames": [
"string"
]
},
"component": {
"proprietaryComponents": true
}
}'
```

### Get information
```shell
curl -X 'GET' \
$NEXUS_HOST/service/rest/v1/repositories/composer/hosted/composer-hosted \
-H 'accept: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true'
```

### Update
```shell
curl -X 'PUT' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/hosted/composer-hosted' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true' \
-d '{
"name": "composer-hosted",
"format": "composer",
"url": "$NEXUS_HOST/repository/composer-hosted",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true,
"writePolicy": "allow_once"
},
"cleanup": {
"policyNames": [
"string"
]
},
"component": {
"proprietaryComponents": false
},
"type": "hosted"
}'
```

## Proxy repository

### Create
```shell
curl -X 'POST' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/proxy' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true' \
-d '{
"name": "composer-proxy",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true
},
"cleanup": {
"policyNames": [
"string"
]
},
"proxy": {
"remoteUrl": "https://packagist.org",
"contentMaxAge": 1440,
"metadataMaxAge": 1440
},
"negativeCache": {
"enabled": true,
"timeToLive": 1440
},
"httpClient": {
"blocked": false,
"autoBlock": true,
"connection": {
"retries": 0,
"userAgentSuffix": "string",
"timeout": 60,
"enableCircularRedirects": false,
"enableCookies": false,
"useTrustStore": false
},
"authentication": {
"type": "username",
"username": "string",
"password": "string",
"ntlmHost": "string",
"ntlmDomain": "string"
}
}
}'
```

### Get information

```shell
curl -X 'GET' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/proxy/composer-proxy' \
-H 'accept: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true'
```

### Update

```shell
curl -X 'PUT' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/proxy/composer-proxy' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true' \
-d '{
"name": "composer-proxy",
"format": "composer",
"url": "$NEXUS_HOST/repository/composer-proxy",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": false
},
"cleanup": {
"policyNames": [
"string"
]
},
"proxy": {
"remoteUrl": "https://packagist.org",
"contentMaxAge": 1440,
"metadataMaxAge": 1440
},
"negativeCache": {
"enabled": true,
"timeToLive": 1440
},
"httpClient": {
"blocked": false,
"autoBlock": true,
"connection": {
"retries": 0,
"userAgentSuffix": "string",
"timeout": 60,
"enableCircularRedirects": false,
"enableCookies": false,
"useTrustStore": false
}
},
"routingRuleName": null,
"type": "proxy"
}'
```

## Group repository

### Create
```shell
curl -X 'POST' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/group' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true' \
-d '{
"name": "composer-group",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true
},
"group": {
"memberNames": [
"composer-hosted"
]
}
}'
```

### Get information

```shell
curl -X 'GET' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/proxy/composer-group' \
-H 'accept: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true'
```

### Update

```shell
curl -X 'PUT' \
'$NEXUS_HOST/service/rest/v1/repositories/composer/group/composer-group' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'NX-ANTI-CSRF-TOKEN: 0.5903676711737454' \
-H 'X-Nexus-UI: true' \
-d '{
"name": "composer-group",
"format": "composer",
"url": "$NEXUS_HOST/repository/composer-group",
"online": true,
"storage": {
"blobStoreName": "default",
"strictContentTypeValidation": true
},
"group": {
"memberNames": [
"composer-hosted",
"composer-proxy"
]
},
"type": "group"
}'
```
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@
*/
package org.sonatype.nexus.repository.composer.internal;

import java.io.File;
import java.io.IOException;
import java.net.URI;

import org.apache.http.entity.ContentType;
import org.sonatype.nexus.testsuite.testsupport.FormatClientSupport;

import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;

import static com.google.common.base.Preconditions.checkNotNull;

public class ComposerClient
extends FormatClientSupport
{ public ComposerClient(
Expand All @@ -28,4 +35,21 @@ public class ComposerClient
{
super(httpClient, httpClientContext, repositoryBaseUri);
}

public int put(final String path, final File file) throws Exception {
checkNotNull(path);
checkNotNull(file);

HttpPut put = new HttpPut(repositoryBaseUri.resolve(path));
put.setEntity(EntityBuilder.create().setContentType(ContentType.parse("application/zip")).setFile(file).build());
return status(execute(put));
}

public int put(String path, String string) throws IOException {
checkNotNull(path);
checkNotNull(string);
HttpPut put = new HttpPut(repositoryBaseUri.resolve(path));
put.setEntity(EntityBuilder.create().setContentType(ContentType.parse("application/json")).setText(string).build());
return status(execute(put));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2018-present Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.repository.composer.internal;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.junit.Before;
import org.junit.Test;
import org.sonatype.nexus.repository.Repository;
import org.sonatype.nexus.repository.http.HttpStatus;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.sonatype.nexus.testsuite.testsupport.FormatClientSupport.status;

public class ComposerGroupIT
extends ComposerITSupport
{
private static final String COMPOSER_TEST_GROUP = "composer-test-group";

private static final String COMPOSER_TEST_HOSTED = "composer-test-hosted";

private ComposerClient groupClient;

private ComposerClient hostedClient;

@Before
public void setup() throws Exception {
startServer();


hostedClient= composerClient(repos.createComposerHosted(COMPOSER_TEST_HOSTED));
Repository groupRepo = repos.createComposerGroup(COMPOSER_TEST_GROUP, COMPOSER_TEST_HOSTED);
groupClient = composerClient(groupRepo);
}

@Test
public void nonExistingPackageProduces404() throws Exception {
assertThat(status(groupClient.get(BAD_PATH)), is(HttpStatus.NOT_FOUND));
}

@Test
public void putAndGetOk() throws Exception {
// given : check package not exists
assertThat(status(groupClient.get(VALID_ZIPBALL_URL)), is(HttpStatus.NOT_FOUND));

// when : upload package on hosted
assertThat(hostedClient.put(NAME_PACKAGES + "/upload/" + VALID_ZIPBALL_BASE_URL, testData.resolveFile(ZIPBALL_FILE_NAME)), is(200));

// then : download on group
assertThat(status(groupClient.get(VALID_ZIPBALL_URL)), is(HttpStatus.OK));
}

@Test
public void checkRestAPI() throws Exception {
assertThat(status(groupClient.get("/service/rest/v1/repositories")), is(HttpStatus.OK));
}

@Test
public void badPutGroupConfigurationByAPI() throws Exception {
assertThat(groupClient.put("/service/rest/v1/repositories/composer/group/" + COMPOSER_TEST_GROUP, "bad request"), is(HttpStatus.BAD_REQUEST));
}

@Test
public void getAndUpdateGroupConfigurationByAPI() throws Exception {
JsonObject expected = new JsonParser().parse("{\"name\":\"composer-test-group\",\"format\":\"composer\",\"online\":true,\"storage\":{\"blobStoreName\":\"default\",\"strictContentTypeValidation\":true},\"group\":{\"memberNames\":[\"composer-test-hosted\"],\"writableMember\":\"None\"},\"type\":\"group\"}").getAsJsonObject();
getAndUpdateConfig(expected, COMPOSER_TEST_GROUP, "group", groupClient);
}
}
Loading

0 comments on commit 45824b5

Please sign in to comment.