diff --git a/.github/workflows/neon.yml b/.github/workflows/neon.yml new file mode 100644 index 00000000..e1626f0c --- /dev/null +++ b/.github/workflows/neon.yml @@ -0,0 +1,21 @@ +name: Neon +on: + push: + branches: + - main + pull_request: + +concurrency: + group: neon-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + untested-apis: + name: Untested APIs + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + + - name: Find untested Neon APIs + run: ./tool/find-untested-neon-apis.sh diff --git a/packages/nextcloud/test/core_test.dart b/packages/nextcloud/test/core_test.dart index 5f4a6326..df5d05aa 100644 --- a/packages/nextcloud/test/core_test.dart +++ b/packages/nextcloud/test/core_test.dart @@ -184,6 +184,21 @@ void main() { expect(response.body.ocs.data.entries.single.rounded, isFalse); expect(response.body.ocs.data.entries.single.attributes, isEmpty); }); + + test('Client login flow V2', () async { + final response = await client.core.clientFlowLoginV2.init(); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.login, startsWith('http://localhost')); + expect(response.body.poll.endpoint, startsWith('http://localhost')); + expect(response.body.poll.token, isNotEmpty); + + expect( + () => client.core.clientFlowLoginV2.poll(token: response.body.poll.token), + throwsA(predicate((final e) => e.statusCode == 404)), + ); + }); }, retry: retryCount, timeout: timeout, diff --git a/packages/nextcloud/test/news_test.dart b/packages/nextcloud/test/news_test.dart index 8e54491f..bac182e2 100644 --- a/packages/nextcloud/test/news_test.dart +++ b/packages/nextcloud/test/news_test.dart @@ -69,6 +69,25 @@ void main() { expect(response.body.feeds[0].url, 'http://host.docker.internal:${rssServer.port}/wikipedia.xml'); }); + test('Delete feed', () async { + var response = await addWikipediaFeed(); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.feeds, hasLength(1)); + + final deleteResponse = await client.news.deleteFeed(feedId: response.body.feeds.single.id); + expect(deleteResponse.statusCode, 200); + expect(() => deleteResponse.body, isA()); + expect(() => deleteResponse.headers, isA()); + + response = await client.news.listFeeds(); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.feeds, hasLength(0)); + }); + test('Rename feed', () async { var response = await addWikipediaFeed(); expect(response.statusCode, 200); @@ -307,6 +326,45 @@ void main() { expect(response.body.folders[0].feeds, hasLength(0)); }); + test('Delete folder', () async { + var response = await client.news.createFolder(name: 'test1'); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.folders, hasLength(1)); + + final deleteResponse = await client.news.deleteFolder(folderId: response.body.folders.single.id); + expect(deleteResponse.statusCode, 200); + expect(() => deleteResponse.body, isA()); + expect(() => deleteResponse.headers, isA()); + + response = await client.news.listFolders(); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.folders, hasLength(0)); + }); + + test('Rename folder', () async { + var response = await client.news.createFolder(name: 'test1'); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.folders, hasLength(1)); + + final deleteResponse = await client.news.renameFolder(folderId: response.body.folders.single.id, name: 'test2'); + expect(deleteResponse.statusCode, 200); + expect(() => deleteResponse.body, isA()); + expect(() => deleteResponse.headers, isA()); + + response = await client.news.listFolders(); + expect(response.statusCode, 200); + expect(() => response.headers, isA()); + + expect(response.body.folders, hasLength(1)); + expect(response.body.folders.single.name, 'test2'); + }); + test('List folders', () async { var response = await client.news.listFolders(); expect(response.statusCode, 200); diff --git a/tool/find-untested-neon-apis.sh b/tool/find-untested-neon-apis.sh new file mode 100755 index 00000000..57dfbfb1 --- /dev/null +++ b/tool/find-untested-neon-apis.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -euxo pipefail +cd "$(dirname "$0")/.." + +function find_apis() { + path="$1" + grep -r "$path" --include "*\.dart" -e "client\.[^.]*.[^(]*(" -oh | sed "s/^client\.//" | sed "s/($//" | sed "s/Raw$//" | sort | uniq +} + +used_apis=("$(find_apis "packages/neon")") +tested_apis=("$(find_apis "packages/nextcloud")") + +untested_apis=() + +for used_api in ${used_apis[*]}; do + tested=0 + + for tested_api in ${tested_apis[*]}; do + if [[ "$tested_api" == "$used_api" ]]; then + tested=1 + break + fi + done + + if [[ "$tested" == 0 ]]; then + untested_apis+=("$used_api") + fi +done + +if [[ -n "${untested_apis[*]}" ]]; then + printf "%s\n" "${untested_apis[@]}" + exit 1 +fi