Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/integration-sqlite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jobs:
- '--tags ~@large files_features'
- 'filesdrop_features'
- 'file_conversions'
- 'files_reminders'
- 'openldap_features'
- 'openldap_numerical_features'
- 'ldap_features'
Expand Down
4 changes: 4 additions & 0 deletions apps/files_reminders/lib/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public function get(int $fileId): DataResponse {
public function set(int $fileId, string $dueDate): DataResponse {
try {
$dueDate = (new DateTime($dueDate))->setTimezone(new DateTimeZone('UTC'));
$nowDate = (new DateTime('now'))->setTimezone(new DateTimeZone('UTC'));
if ($dueDate <= $nowDate) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
} catch (Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
return new DataResponse([], Http::STATUS_BAD_REQUEST);
Expand Down
10 changes: 10 additions & 0 deletions build/integration/config/behat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ default:
- admin
- admin
regular_user_password: 123456
files_reminders:
paths:
- "%paths.base%/../files_reminders"
contexts:
- FilesRemindersContext:
baseUrl: http://localhost:8080
admin:
- admin
- admin
regular_user_password: 123456
capabilities:
paths:
- "%paths.base%/../capabilities_features"
Expand Down
23 changes: 16 additions & 7 deletions build/integration/features/bootstrap/BasicStructure.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,27 @@ public function sendingTo($verb, $url) {
}

/**
* Parses the xml answer to get ocs response which doesn't match with
* Parses the xml or json answer to get ocs response which doesn't match with
* http one in v1 of the api.
*
* @param ResponseInterface $response
* @return string
*/
public function getOCSResponse($response) {
$body = simplexml_load_string((string)$response->getBody());
if ($body === false) {
throw new \RuntimeException('Could not parse OCS response, body is not valid XML');
public function getOCSResponseCode($response): int {
if ($response === null) {
throw new \RuntimeException('No response available');
}
return $body->meta[0]->statuscode;

$body = (string)$response->getBody();
if (str_starts_with($body, '<')) {
$body = simplexml_load_string($body);
if ($body === false) {
throw new \RuntimeException('Could not parse OCS response, body is not valid XML');
}
return (int)$body->meta[0]->statuscode;
}

return json_decode($body, true)['ocs']['meta']['statuscode'];
}

/**
Expand Down Expand Up @@ -256,7 +265,7 @@ public function isExpectedUrl($possibleUrl, $finalPart) {
* @param int $statusCode
*/
public function theOCSStatusCodeShouldBe($statusCode) {
Assert::assertEquals($statusCode, $this->getOCSResponse($this->response));
Assert::assertEquals($statusCode, $this->getOCSResponseCode($this->response));
}

/**
Expand Down
96 changes: 96 additions & 0 deletions build/integration/features/bootstrap/FilesRemindersContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
use Behat\Behat\Context\Context;
use PHPUnit\Framework\Assert;

require __DIR__ . '/../../vendor/autoload.php';


/**
* Files reminders context.
*/
class FilesRemindersContext implements Context {
use BasicStructure;
use WebDav;

/**
* @When the user sets a reminder for :path with due date :dueDate
*/
public function settingAReminderForFileWithDueDate($path, $dueDate) {
$fileId = $this->getFileIdForPath($this->currentUser, $path);
$this->sendRequestForJSON(
'PUT',
'/apps/files_reminders/api/v1/' . $fileId,
['dueDate' => $dueDate],
['OCS-APIREQUEST' => 'true']
);
}

/**
* @Then the user sees the reminder for :path is set to :dueDate
*/
public function retrievingTheReminderForFile($path, $dueDate) {
$fileId = $this->getFileIdForPath($this->currentUser, $path);
$this->sendRequestForJSON(
'GET',
'/apps/files_reminders/api/v1/' . $fileId,
null,
['OCS-APIREQUEST' => 'true']
);
$response = $this->getDueDateFromOCSResponse();
Assert::assertEquals($dueDate, $response);
}

/**
* @Then the user sees the reminder for :path is not set
*/
public function retrievingTheReminderForFileIsNotSet($path) {
$fileId = $this->getFileIdForPath($this->currentUser, $path);
$this->sendRequestForJSON(
'GET',
'/apps/files_reminders/api/v1/' . $fileId,
null,
['OCS-APIREQUEST' => 'true']
);
$response = $this->getDueDateFromOCSResponse();
Assert::assertNull($response);
}

/**
* @When the user removes the reminder for :path
*/
public function removingTheReminderForFile($path) {
$fileId = $this->getFileIdForPath($this->currentUser, $path);
$this->sendRequestForJSON(
'DELETE',
'/apps/files_reminders/api/v1/' . $fileId,
null,
['OCS-APIREQUEST' => 'true']
);
}

/**
* Check the due date from OCS response
*/
private function getDueDateFromOCSResponse(): ?string {
if ($this->response === null) {
throw new \RuntimeException('No response available');
}

$body = (string)$this->response->getBody();
if (str_starts_with($body, '<')) {
$body = simplexml_load_string($body);
if ($body === false) {
throw new \RuntimeException('Could not parse OCS response, body is not valid XML');
}
return $body->data->dueDate;
}

$body = json_decode($body, true);
return $body['ocs']['data']['dueDate'] ?? null;
}
}
33 changes: 33 additions & 0 deletions build/integration/files_reminders/files_reminders.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-only
Feature: Files reminders

Background:
Given using api version "2"

Scenario: Set a reminder with a past due date
Given user "user0" exists
Given As an "user0"
Given User "user0" uploads file "data/textfile.txt" to "/file.txt"
When the user sets a reminder for "/file.txt" with due date "2000-01-01T00:00:00Z"
Then the OCS status code should be "400"
Then the user sees the reminder for "/file.txt" is not set

Scenario: Set a reminder with a valid due date
Given user "user1" exists
Given As an "user1"
Given User "user1" uploads file "data/textfile.txt" to "/file.txt"
When the user sets a reminder for "/file.txt" with due date "2100-01-01T00:00:00Z"
Then the OCS status code should be "201"
Then the user sees the reminder for "/file.txt" is set to "2100-01-01T00:00:00+00:00"

Scenario: Remove a reminder
Given user "user2" exists
Given As an "user2"
Given User "user2" uploads file "data/textfile.txt" to "/file.txt"
When the user sets a reminder for "/file.txt" with due date "2100-01-01T00:00:00Z"
Then the OCS status code should be "201"
Then the user sees the reminder for "/file.txt" is set to "2100-01-01T00:00:00+00:00"
When the user removes the reminder for "/file.txt"
Then the OCS status code should be "200"
Then the user sees the reminder for "/file.txt" is not set
Loading