From febce4f2e3a86da4171783fcc593b25a807c3da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Sat, 25 Aug 2018 11:53:14 -0700 Subject: [PATCH] Split integration tests into multiple files --- Makefile | 2 +- integration_test.go | 1266 ----------------------------------- tests/category_test.go | 153 +++++ tests/doc.go | 10 + tests/endpoint_test.go | 21 + tests/entry_test.go | 225 +++++++ tests/feed_test.go | 390 +++++++++++ tests/import_export_test.go | 46 ++ tests/subscription_test.go | 35 + tests/tests.go | 68 ++ tests/user_test.go | 380 +++++++++++ 11 files changed, 1329 insertions(+), 1267 deletions(-) delete mode 100644 integration_test.go create mode 100644 tests/category_test.go create mode 100644 tests/doc.go create mode 100644 tests/endpoint_test.go create mode 100644 tests/entry_test.go create mode 100644 tests/feed_test.go create mode 100644 tests/import_export_test.go create mode 100644 tests/subscription_test.go create mode 100644 tests/tests.go create mode 100644 tests/user_test.go diff --git a/Makefile b/Makefile index 1063ed3a..78985bd9 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ integration-test: go build -o miniflux-test main.go DATABASE_URL=$(DB_URL) ./miniflux-test -debug >/tmp/miniflux.log 2>&1 & echo "$$!" > "/tmp/miniflux.pid" while ! echo exit | nc localhost 8080; do sleep 1; done >/dev/null - go test -v -tags=integration || cat /tmp/miniflux.log + go test -v -tags=integration miniflux.app/tests || cat /tmp/miniflux.log clean-integration-test: @ kill -9 `cat /tmp/miniflux.pid` diff --git a/integration_test.go b/integration_test.go deleted file mode 100644 index bed090e3..00000000 --- a/integration_test.go +++ /dev/null @@ -1,1266 +0,0 @@ -// Copyright 2017 Frédéric Guillot. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// +build integration - -package main - -import ( - "bytes" - "io/ioutil" - "math/rand" - "strconv" - "strings" - "testing" - "time" - - miniflux "miniflux.app/client" -) - -const ( - testBaseURL = "http://127.0.0.1:8080/" - testAdminUsername = "admin" - testAdminPassword = "test123" - testStandardPassword = "secret" - testFeedURL = "https://github.com/miniflux/miniflux/commits/master.atom" - testFeedTitle = "Recent Commits to miniflux:master" - testWebsiteURL = "https://github.com/miniflux/miniflux/commits/master" -) - -func TestWithBadEndpoint(t *testing.T) { - client := miniflux.New("bad url", testAdminUsername, testAdminPassword) - _, err := client.Users() - if err == nil { - t.Fatal(`Using a bad url should raise an error`) - } -} - -func TestWithWrongCredentials(t *testing.T) { - client := miniflux.New(testBaseURL, "invalid", "invalid") - _, err := client.Users() - if err == nil { - t.Fatal(`Using bad credentials should raise an error`) - } - - if err != miniflux.ErrNotAuthorized { - t.Fatal(`A "Not Authorized" error should be raised`) - } -} - -func TestGetCurrentLoggedUser(t *testing.T) { - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.Me() - if err != nil { - t.Fatal(err) - } - - if user.ID == 0 { - t.Fatalf(`Invalid userID, got %q`, user.ID) - } - - if user.Username != testAdminUsername { - t.Fatalf(`Invalid username, got %q`, user.Username) - } -} - -func TestGetUsers(t *testing.T) { - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - users, err := client.Users() - if err != nil { - t.Fatal(err) - } - - if len(users) == 0 { - t.Fatal("The list of users is empty") - } - - if users[0].ID == 0 { - t.Fatalf(`Invalid userID, got "%v"`, users[0].ID) - } - - if users[0].Username != testAdminUsername { - t.Fatalf(`Invalid username, got "%v" instead of "%v"`, users[0].Username, testAdminUsername) - } - - if users[0].Password != "" { - t.Fatalf(`Invalid password, got "%v"`, users[0].Password) - } - - if users[0].Language != "en_US" { - t.Fatalf(`Invalid language, got "%v"`, users[0].Language) - } - - if users[0].Theme != "default" { - t.Fatalf(`Invalid theme, got "%v"`, users[0].Theme) - } - - if users[0].Timezone != "UTC" { - t.Fatalf(`Invalid timezone, got "%v"`, users[0].Timezone) - } - - if !users[0].IsAdmin { - t.Fatalf(`Invalid role, got "%v"`, users[0].IsAdmin) - } -} - -func TestCreateStandardUser(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - if user.ID == 0 { - t.Fatalf(`Invalid userID, got "%v"`, user.ID) - } - - if user.Username != username { - t.Fatalf(`Invalid username, got "%v" instead of "%v"`, user.Username, username) - } - - if user.Password != "" { - t.Fatalf(`Invalid password, got "%v"`, user.Password) - } - - if user.Language != "en_US" { - t.Fatalf(`Invalid language, got "%v"`, user.Language) - } - - if user.Theme != "default" { - t.Fatalf(`Invalid theme, got "%v"`, user.Theme) - } - - if user.Timezone != "UTC" { - t.Fatalf(`Invalid timezone, got "%v"`, user.Timezone) - } - - if user.IsAdmin { - t.Fatalf(`Invalid role, got "%v"`, user.IsAdmin) - } - - if user.LastLoginAt != nil { - t.Fatalf(`Invalid last login date, got "%v"`, user.LastLoginAt) - } -} - -func TestRemoveUser(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - if err := client.DeleteUser(user.ID); err != nil { - t.Fatalf(`Unable to remove user: "%v"`, err) - } -} - -func TestGetUserByID(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - _, err = client.UserByID(99999) - if err == nil { - t.Fatal(`Should returns a 404`) - } - - user, err = client.UserByID(user.ID) - if err != nil { - t.Fatal(err) - } - - if user.ID == 0 { - t.Fatalf(`Invalid userID, got "%v"`, user.ID) - } - - if user.Username != username { - t.Fatalf(`Invalid username, got "%v" instead of "%v"`, user.Username, username) - } - - if user.Password != "" { - t.Fatalf(`Invalid password, got "%v"`, user.Password) - } - - if user.Language != "en_US" { - t.Fatalf(`Invalid language, got "%v"`, user.Language) - } - - if user.Theme != "default" { - t.Fatalf(`Invalid theme, got "%v"`, user.Theme) - } - - if user.Timezone != "UTC" { - t.Fatalf(`Invalid timezone, got "%v"`, user.Timezone) - } - - if user.IsAdmin { - t.Fatalf(`Invalid role, got "%v"`, user.IsAdmin) - } - - if user.LastLoginAt != nil { - t.Fatalf(`Invalid last login date, got "%v"`, user.LastLoginAt) - } -} - -func TestGetUserByUsername(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - _, err = client.UserByUsername("missinguser") - if err == nil { - t.Fatal(`Should returns a 404`) - } - - user, err = client.UserByUsername(username) - if err != nil { - t.Fatal(err) - } - - if user.ID == 0 { - t.Fatalf(`Invalid userID, got "%v"`, user.ID) - } - - if user.Username != username { - t.Fatalf(`Invalid username, got "%v" instead of "%v"`, user.Username, username) - } - - if user.Password != "" { - t.Fatalf(`Invalid password, got "%v"`, user.Password) - } - - if user.Language != "en_US" { - t.Fatalf(`Invalid language, got "%v"`, user.Language) - } - - if user.Theme != "default" { - t.Fatalf(`Invalid theme, got "%v"`, user.Theme) - } - - if user.Timezone != "UTC" { - t.Fatalf(`Invalid timezone, got "%v"`, user.Timezone) - } - - if user.IsAdmin { - t.Fatalf(`Invalid role, got "%v"`, user.IsAdmin) - } - - if user.LastLoginAt != nil { - t.Fatalf(`Invalid last login date, got "%v"`, user.LastLoginAt) - } -} - -func TestUpdateUserTheme(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - theme := "black" - user, err = client.UpdateUser(user.ID, &miniflux.UserModification{Theme: &theme}) - if err != nil { - t.Fatal(err) - } - - if user.Theme != theme { - t.Fatalf(`Unable to update user Theme: got "%v" instead of "%v"`, user.Theme, theme) - } -} - -func TestUpdateUserThemeWithInvalidValue(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - theme := "something that doesn't exists" - _, err = client.UpdateUser(user.ID, &miniflux.UserModification{Theme: &theme}) - if err == nil { - t.Fatal(`Updating a user Theme with an invalid value should raise an error`) - } -} - -func TestCannotCreateDuplicateUser(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - _, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - _, err = client.CreateUser(username, testStandardPassword, false) - if err == nil { - t.Fatal(`Duplicate users should not be allowed`) - } -} - -func TestCannotListUsersAsNonAdmin(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - _, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - _, err = client.Users() - if err == nil { - t.Fatal(`Standard users should not be able to list any users`) - } - - if err != miniflux.ErrForbidden { - t.Fatal(`A "Forbidden" error should be raised`) - } -} - -func TestCannotGetUserAsNonAdmin(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - _, err = client.UserByID(user.ID) - if err == nil { - t.Fatal(`Standard users should not be able to get any users`) - } - - if err != miniflux.ErrForbidden { - t.Fatal(`A "Forbidden" error should be raised`) - } -} - -func TestCannotUpdateUserAsNonAdmin(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - _, err = client.UpdateUser(user.ID, &miniflux.UserModification{}) - if err == nil { - t.Fatal(`Standard users should not be able to update any users`) - } - - if err != miniflux.ErrForbidden { - t.Fatal(`A "Forbidden" error should be raised`) - } -} - -func TestCannotCreateUserAsNonAdmin(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - _, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - _, err = client.CreateUser(username, testStandardPassword, false) - if err == nil { - t.Fatal(`Standard users should not be able to create users`) - } - - if err != miniflux.ErrForbidden { - t.Fatal(`A "Forbidden" error should be raised`) - } -} - -func TestCannotDeleteUserAsNonAdmin(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - err = client.DeleteUser(user.ID) - if err == nil { - t.Fatal(`Standard users should not be able to remove any users`) - } - - if err != miniflux.ErrForbidden { - t.Fatal(`A "Forbidden" error should be raised`) - } -} - -func TestCreateCategory(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - categoryName := "My category" - client = miniflux.New(testBaseURL, username, testStandardPassword) - category, err := client.CreateCategory(categoryName) - if err != nil { - t.Fatal(err) - } - - if category.ID == 0 { - t.Fatalf(`Invalid categoryID, got "%v"`, category.ID) - } - - if category.UserID != user.ID { - t.Fatalf(`Invalid userID, got "%v" instead of "%v"`, category.UserID, user.ID) - } - - if category.Title != categoryName { - t.Fatalf(`Invalid title, got "%v" instead of "%v"`, category.Title, categoryName) - } -} - -func TestCreateCategoryWithEmptyTitle(t *testing.T) { - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - _, err := client.CreateCategory("") - if err == nil { - t.Fatal(`The category title should be mandatory`) - } -} - -func TestCannotCreateDuplicatedCategory(t *testing.T) { - client := createClient(t) - - categoryName := "My category" - _, err := client.CreateCategory(categoryName) - if err != nil { - t.Fatal(err) - } - - _, err = client.CreateCategory(categoryName) - if err == nil { - t.Fatal(`Duplicated categories should not be allowed`) - } -} - -func TestUpdateCategory(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - categoryName := "My category" - client = miniflux.New(testBaseURL, username, testStandardPassword) - category, err := client.CreateCategory(categoryName) - if err != nil { - t.Fatal(err) - } - - categoryName = "Updated category" - category, err = client.UpdateCategory(category.ID, categoryName) - if err != nil { - t.Fatal(err) - } - - if category.ID == 0 { - t.Fatalf(`Invalid categoryID, got "%v"`, category.ID) - } - - if category.UserID != user.ID { - t.Fatalf(`Invalid userID, got "%v" instead of "%v"`, category.UserID, user.ID) - } - - if category.Title != categoryName { - t.Fatalf(`Invalid title, got "%v" instead of "%v"`, category.Title, categoryName) - } -} - -func TestListCategories(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - user, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - categoryName := "My category" - client = miniflux.New(testBaseURL, username, testStandardPassword) - _, err = client.CreateCategory(categoryName) - if err != nil { - t.Fatal(err) - } - - categories, err := client.Categories() - if err != nil { - t.Fatal(err) - } - - if len(categories) != 2 { - t.Fatalf(`Invalid number of categories, got "%v" instead of "%v"`, len(categories), 2) - } - - if categories[0].ID == 0 { - t.Fatalf(`Invalid categoryID, got "%v"`, categories[0].ID) - } - - if categories[0].UserID != user.ID { - t.Fatalf(`Invalid userID, got "%v" instead of "%v"`, categories[0].UserID, user.ID) - } - - if categories[0].Title != "All" { - t.Fatalf(`Invalid title, got "%v" instead of "%v"`, categories[0].Title, "All") - } - - if categories[1].ID == 0 { - t.Fatalf(`Invalid categoryID, got "%v"`, categories[0].ID) - } - - if categories[1].UserID != user.ID { - t.Fatalf(`Invalid userID, got "%v" instead of "%v"`, categories[1].UserID, user.ID) - } - - if categories[1].Title != categoryName { - t.Fatalf(`Invalid title, got "%v" instead of "%v"`, categories[1].Title, categoryName) - } -} - -func TestDeleteCategory(t *testing.T) { - client := createClient(t) - - category, err := client.CreateCategory("My category") - if err != nil { - t.Fatal(err) - } - - err = client.DeleteCategory(category.ID) - if err != nil { - t.Fatal(`Removing a category should not raise any error`) - } -} - -func TestCannotDeleteCategoryOfAnotherUser(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - categories, err := client.Categories() - if err != nil { - t.Fatal(err) - } - - _, err = client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - err = client.DeleteCategory(categories[0].ID) - if err == nil { - t.Fatal(`Removing a category that belongs to another user should be forbidden`) - } -} - -func TestDiscoverSubscriptions(t *testing.T) { - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - subscriptions, err := client.Discover(testWebsiteURL) - if err != nil { - t.Fatal(err) - } - - if len(subscriptions) != 1 { - t.Fatalf(`Invalid number of subscriptions, got "%v" instead of "%v"`, len(subscriptions), 2) - } - - if subscriptions[0].Title != testFeedTitle { - t.Fatalf(`Invalid feed title, got "%v" instead of "%v"`, subscriptions[0].Title, testFeedTitle) - } - - if subscriptions[0].Type != "atom" { - t.Fatalf(`Invalid feed type, got "%v" instead of "%v"`, subscriptions[0].Type, "atom") - } - - if subscriptions[0].URL != testFeedURL { - t.Fatalf(`Invalid feed URL, got "%v" instead of "%v"`, subscriptions[0].URL, testFeedURL) - } -} - -func TestCreateFeed(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - if feed.ID == 0 { - t.Fatalf(`Invalid feed ID, got %q`, feed.ID) - } -} - -func TestCannotCreateDuplicatedFeed(t *testing.T) { - client := createClient(t) - feed, category := createFeed(t, client) - - _, err := client.CreateFeed(feed.FeedURL, category.ID) - if err == nil { - t.Fatal(`Duplicated feeds should not be allowed`) - } -} - -func TestCreateFeedWithInexistingCategory(t *testing.T) { - client := createClient(t) - - _, err := client.CreateFeed(testFeedURL, -1) - if err == nil { - t.Fatal(`Feeds should not be created with inexisting category`) - } -} - -func TestExport(t *testing.T) { - client := createClient(t) - - output, err := client.Export() - if err != nil { - t.Fatal(err) - } - - if !strings.HasPrefix(string(output), " - - - - - - - ` - - b := bytes.NewReader([]byte(data)) - err := client.Import(ioutil.NopCloser(b)) - if err != nil { - t.Fatal(err) - } -} - -func TestUpdateFeedURL(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - url := "test" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{FeedURL: &url}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.FeedURL != url { - t.Fatalf(`Wrong FeedURL, got %q instead of %q`, updatedFeed.FeedURL, url) - } - - url = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{FeedURL: &url}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.FeedURL == "" { - t.Fatalf(`The FeedURL should not be empty`) - } -} - -func TestUpdateFeedSiteURL(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - url := "test" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{SiteURL: &url}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.SiteURL != url { - t.Fatalf(`Wrong SiteURL, got %q instead of %q`, updatedFeed.SiteURL, url) - } - - url = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{SiteURL: &url}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.SiteURL == "" { - t.Fatalf(`The SiteURL should not be empty`) - } -} - -func TestUpdateFeedTitle(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - newTitle := "My new feed" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Title: &newTitle}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Title != newTitle { - t.Fatalf(`Wrong title, got %q instead of %q`, updatedFeed.Title, newTitle) - } - - newTitle = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Title: &newTitle}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Title == "" { - t.Fatalf(`The Title should not be empty`) - } -} - -func TestUpdateFeedCrawler(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - crawler := true - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Crawler: &crawler}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Crawler != crawler { - t.Fatalf(`Wrong crawler value, got "%v" instead of "%v"`, updatedFeed.Crawler, crawler) - } - - if updatedFeed.Title != feed.Title { - t.Fatalf(`The titles should be the same after update`) - } - - crawler = false - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Crawler: &crawler}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Crawler != crawler { - t.Fatalf(`Wrong crawler value, got "%v" instead of "%v"`, updatedFeed.Crawler, crawler) - } -} - -func TestUpdateFeedScraperRules(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - scraperRules := "test" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{ScraperRules: &scraperRules}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.ScraperRules != scraperRules { - t.Fatalf(`Wrong ScraperRules value, got "%v" instead of "%v"`, updatedFeed.ScraperRules, scraperRules) - } - - scraperRules = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{ScraperRules: &scraperRules}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.ScraperRules != scraperRules { - t.Fatalf(`Wrong ScraperRules value, got "%v" instead of "%v"`, updatedFeed.ScraperRules, scraperRules) - } -} - -func TestUpdateFeedRewriteRules(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - rewriteRules := "test" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{RewriteRules: &rewriteRules}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.RewriteRules != rewriteRules { - t.Fatalf(`Wrong RewriteRules value, got "%v" instead of "%v"`, updatedFeed.RewriteRules, rewriteRules) - } - - rewriteRules = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{RewriteRules: &rewriteRules}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.RewriteRules != rewriteRules { - t.Fatalf(`Wrong RewriteRules value, got "%v" instead of "%v"`, updatedFeed.RewriteRules, rewriteRules) - } -} - -func TestUpdateFeedUsername(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - username := "test" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Username: &username}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Username != username { - t.Fatalf(`Wrong Username value, got "%v" instead of "%v"`, updatedFeed.Username, username) - } - - username = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Username: &username}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Username != username { - t.Fatalf(`Wrong Username value, got "%v" instead of "%v"`, updatedFeed.Username, username) - } -} - -func TestUpdateFeedPassword(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - password := "test" - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Password: &password}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Password != password { - t.Fatalf(`Wrong Password value, got "%v" instead of "%v"`, updatedFeed.Password, password) - } - - password = "" - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Password: &password}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Password != password { - t.Fatalf(`Wrong Password value, got "%v" instead of "%v"`, updatedFeed.Password, password) - } -} - -func TestUpdateFeedCategory(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - newCategory, err := client.CreateCategory("my new category") - if err != nil { - t.Fatal(err) - } - - updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{CategoryID: &newCategory.ID}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Category.ID != newCategory.ID { - t.Fatalf(`Wrong CategoryID value, got "%v" instead of "%v"`, updatedFeed.Category.ID, newCategory.ID) - } - - categoryID := int64(0) - updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{CategoryID: &categoryID}) - if err != nil { - t.Fatal(err) - } - - if updatedFeed.Category.ID == 0 { - t.Fatalf(`The CategoryID must defined`) - } -} - -func TestDeleteFeed(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - if err := client.DeleteFeed(feed.ID); err != nil { - t.Fatal(err) - } -} - -func TestRefreshFeed(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - if err := client.RefreshFeed(feed.ID); err != nil { - t.Fatal(err) - } -} - -func TestGetFeed(t *testing.T) { - client := createClient(t) - feed, category := createFeed(t, client) - - if feed.Title != testFeedTitle { - t.Fatalf(`Invalid feed title, got "%v" instead of "%v"`, feed.Title, testFeedTitle) - } - - if feed.SiteURL != testWebsiteURL { - t.Fatalf(`Invalid site URL, got "%v" instead of "%v"`, feed.SiteURL, testWebsiteURL) - } - - if feed.FeedURL != testFeedURL { - t.Fatalf(`Invalid feed URL, got "%v" instead of "%v"`, feed.FeedURL, testFeedURL) - } - - if feed.Category.ID != category.ID { - t.Fatalf(`Invalid feed category ID, got "%v" instead of "%v"`, feed.Category.ID, category.ID) - } - - if feed.Category.UserID != category.UserID { - t.Fatalf(`Invalid feed category user ID, got "%v" instead of "%v"`, feed.Category.UserID, category.UserID) - } - - if feed.Category.Title != category.Title { - t.Fatalf(`Invalid feed category title, got "%v" instead of "%v"`, feed.Category.Title, category.Title) - } -} - -func TestGetFeedIcon(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - feedIcon, err := client.FeedIcon(feed.ID) - if err != nil { - t.Fatal(err) - } - - if feedIcon.ID == 0 { - t.Fatalf(`Invalid feed icon ID, got "%v"`, feedIcon.ID) - } - - if feedIcon.MimeType != "image/x-icon" { - t.Fatalf(`Invalid feed icon mime type, got "%v" instead of "%v"`, feedIcon.MimeType, "image/x-icon") - } - - if !strings.Contains(feedIcon.Data, "image/x-icon") { - t.Fatalf(`Invalid feed icon data, got "%v"`, feedIcon.Data) - } -} - -func TestGetFeedIconNotFound(t *testing.T) { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - _, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - client = miniflux.New(testBaseURL, username, testStandardPassword) - if _, err := client.FeedIcon(42); err == nil { - t.Fatalf(`The feed icon should be null`) - } -} - -func TestGetFeeds(t *testing.T) { - client := createClient(t) - feed, category := createFeed(t, client) - - feeds, err := client.Feeds() - if err != nil { - t.Fatal(err) - } - - if len(feeds) != 1 { - t.Fatalf(`Invalid number of feeds`) - } - - if feeds[0].ID != feed.ID { - t.Fatalf(`Invalid feed ID, got "%v" instead of "%v"`, feeds[0].ID, feed.ID) - } - - if feeds[0].Title != testFeedTitle { - t.Fatalf(`Invalid feed title, got "%v" instead of "%v"`, feeds[0].Title, testFeedTitle) - } - - if feeds[0].SiteURL != testWebsiteURL { - t.Fatalf(`Invalid site URL, got "%v" instead of "%v"`, feeds[0].SiteURL, testWebsiteURL) - } - - if feeds[0].FeedURL != testFeedURL { - t.Fatalf(`Invalid feed URL, got "%v" instead of "%v"`, feeds[0].FeedURL, testFeedURL) - } - - if feeds[0].Category.ID != category.ID { - t.Fatalf(`Invalid feed category ID, got "%v" instead of "%v"`, feeds[0].Category.ID, category.ID) - } - - if feeds[0].Category.UserID != category.UserID { - t.Fatalf(`Invalid feed category user ID, got "%v" instead of "%v"`, feeds[0].Category.UserID, category.UserID) - } - - if feeds[0].Category.Title != category.Title { - t.Fatalf(`Invalid feed category title, got "%v" instead of "%v"`, feeds[0].Category.Title, category.Title) - } -} - -func TestGetAllFeedEntries(t *testing.T) { - client := createClient(t) - feed, _ := createFeed(t, client) - - allResults, err := client.FeedEntries(feed.ID, nil) - if err != nil { - t.Fatal(err) - } - - if allResults.Total == 0 { - t.Fatal(`Invalid number of entries`) - } - - if allResults.Entries[0].Title == "" { - t.Fatal(`Invalid entry title`) - } - - filteredResults, err := client.FeedEntries(feed.ID, &miniflux.Filter{Limit: 1, Offset: 5}) - if err != nil { - t.Fatal(err) - } - - if allResults.Total != filteredResults.Total { - t.Fatal(`Total should always contains the total number of items regardless of filters`) - } - - if allResults.Entries[0].ID == filteredResults.Entries[0].ID { - t.Fatal(`Filtered entries should be different than previous results`) - } - - filteredResultsByEntryID, err := client.FeedEntries(feed.ID, &miniflux.Filter{BeforeEntryID: allResults.Entries[0].ID}) - if err != nil { - t.Fatal(err) - } - - if filteredResultsByEntryID.Entries[0].ID == allResults.Entries[0].ID { - t.Fatal(`The first entry should filtered out`) - } -} - -func TestGetAllEntries(t *testing.T) { - client := createClient(t) - createFeed(t, client) - - resultWithoutSorting, err := client.Entries(nil) - if err != nil { - t.Fatal(err) - } - - if resultWithoutSorting.Total == 0 { - t.Fatal(`Invalid number of entries`) - } - - resultWithStatusFilter, err := client.Entries(&miniflux.Filter{Status: miniflux.EntryStatusRead}) - if err != nil { - t.Fatal(err) - } - - if resultWithStatusFilter.Total != 0 { - t.Fatal(`We should have 0 read entries`) - } - - resultWithDifferentSorting, err := client.Entries(&miniflux.Filter{Order: "published_at", Direction: "desc"}) - if err != nil { - t.Fatal(err) - } - - if resultWithDifferentSorting.Entries[0].Title == resultWithoutSorting.Entries[0].Title { - t.Fatalf(`The items should be sorted differently "%v" vs "%v"`, resultWithDifferentSorting.Entries[0].Title, resultWithoutSorting.Entries[0].Title) - } - - resultWithStarredEntries, err := client.Entries(&miniflux.Filter{Starred: true}) - if err != nil { - t.Fatal(err) - } - - if resultWithStarredEntries.Total != 0 { - t.Fatalf(`We are not supposed to have starred entries yet`) - } -} - -func TestSearchEntries(t *testing.T) { - client := createClient(t) - categories, err := client.Categories() - if err != nil { - t.Fatal(err) - } - - feedID, err := client.CreateFeed("https://github.com/miniflux/miniflux/releases.atom", categories[0].ID) - if err != nil { - t.Fatal(err) - } - - if feedID == 0 { - t.Fatalf(`Invalid feed ID, got %q`, feedID) - } - - results, err := client.Entries(&miniflux.Filter{Search: "2.0.8"}) - if err != nil { - t.Fatal(err) - } - - if results.Total != 1 { - t.Fatalf(`We should have only one entry instead of %d`, results.Total) - } -} - -func TestInvalidFilters(t *testing.T) { - client := createClient(t) - createFeed(t, client) - - _, err := client.Entries(&miniflux.Filter{Status: "invalid"}) - if err == nil { - t.Fatal(`Using invalid status should raise an error`) - } - - _, err = client.Entries(&miniflux.Filter{Direction: "invalid"}) - if err == nil { - t.Fatal(`Using invalid direction should raise an error`) - } - - _, err = client.Entries(&miniflux.Filter{Order: "invalid"}) - if err == nil { - t.Fatal(`Using invalid order should raise an error`) - } -} - -func TestGetEntry(t *testing.T) { - client := createClient(t) - createFeed(t, client) - - result, err := client.Entries(&miniflux.Filter{Limit: 1}) - if err != nil { - t.Fatal(err) - } - - entry, err := client.FeedEntry(result.Entries[0].FeedID, result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - if entry.ID != result.Entries[0].ID { - t.Fatal("Wrong entry returned") - } - - entry, err = client.Entry(result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - if entry.ID != result.Entries[0].ID { - t.Fatal("Wrong entry returned") - } -} - -func TestUpdateStatus(t *testing.T) { - client := createClient(t) - createFeed(t, client) - - result, err := client.Entries(&miniflux.Filter{Limit: 1}) - if err != nil { - t.Fatal(err) - } - - err = client.UpdateEntries([]int64{result.Entries[0].ID}, miniflux.EntryStatusRead) - if err != nil { - t.Fatal(err) - } - - entry, err := client.Entry(result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - if entry.Status != miniflux.EntryStatusRead { - t.Fatal("The entry status should be updated") - } - - err = client.UpdateEntries([]int64{result.Entries[0].ID}, "invalid") - if err == nil { - t.Fatal(`Invalid entry status should ne be accepted`) - } -} - -func TestToggleBookmark(t *testing.T) { - client := createClient(t) - createFeed(t, client) - - result, err := client.Entries(&miniflux.Filter{Limit: 1}) - if err != nil { - t.Fatal(err) - } - - if result.Entries[0].Starred { - t.Fatal("The entry should not be starred") - } - - err = client.ToggleBookmark(result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - entry, err := client.Entry(result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - if !entry.Starred { - t.Fatal("The entry should be starred") - } -} - -func getRandomUsername() string { - rand.Seed(time.Now().UnixNano()) - var suffix []string - for i := 0; i < 10; i++ { - suffix = append(suffix, strconv.Itoa(rand.Intn(1000))) - } - return "user" + strings.Join(suffix, "") -} - -func createClient(t *testing.T) *miniflux.Client { - username := getRandomUsername() - client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) - _, err := client.CreateUser(username, testStandardPassword, false) - if err != nil { - t.Fatal(err) - } - - return miniflux.New(testBaseURL, username, testStandardPassword) -} - -func createFeed(t *testing.T, client *miniflux.Client) (*miniflux.Feed, *miniflux.Category) { - categories, err := client.Categories() - if err != nil { - t.Fatal(err) - } - - feedID, err := client.CreateFeed(testFeedURL, categories[0].ID) - if err != nil { - t.Fatal(err) - } - - if feedID == 0 { - t.Fatalf(`Invalid feed ID, got %q`, feedID) - } - - feed, err := client.Feed(feedID) - if err != nil { - t.Fatal(err) - } - - return feed, categories[0] -} diff --git a/tests/category_test.go b/tests/category_test.go new file mode 100644 index 00000000..8aa3d6b1 --- /dev/null +++ b/tests/category_test.go @@ -0,0 +1,153 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "testing" +) + +func TestCreateCategory(t *testing.T) { + categoryName := "My category" + client := createClient(t) + category, err := client.CreateCategory(categoryName) + if err != nil { + t.Fatal(err) + } + + if category.ID == 0 { + t.Fatalf(`Invalid categoryID, got "%v"`, category.ID) + } + + if category.UserID <= 0 { + t.Fatalf(`Invalid userID, got "%v"`, category.UserID) + } + + if category.Title != categoryName { + t.Fatalf(`Invalid title, got "%v" instead of "%v"`, category.Title, categoryName) + } +} + +func TestCreateCategoryWithEmptyTitle(t *testing.T) { + client := createClient(t) + _, err := client.CreateCategory("") + if err == nil { + t.Fatal(`The category title should be mandatory`) + } +} + +func TestCannotCreateDuplicatedCategory(t *testing.T) { + client := createClient(t) + + categoryName := "My category" + _, err := client.CreateCategory(categoryName) + if err != nil { + t.Fatal(err) + } + + _, err = client.CreateCategory(categoryName) + if err == nil { + t.Fatal(`Duplicated categories should not be allowed`) + } +} + +func TestUpdateCategory(t *testing.T) { + categoryName := "My category" + client := createClient(t) + category, err := client.CreateCategory(categoryName) + if err != nil { + t.Fatal(err) + } + + categoryName = "Updated category" + category, err = client.UpdateCategory(category.ID, categoryName) + if err != nil { + t.Fatal(err) + } + + if category.ID == 0 { + t.Fatalf(`Invalid categoryID, got "%v"`, category.ID) + } + + if category.UserID <= 0 { + t.Fatalf(`Invalid userID, got "%v"`, category.UserID) + } + + if category.Title != categoryName { + t.Fatalf(`Invalid title, got "%v" instead of "%v"`, category.Title, categoryName) + } +} + +func TestListCategories(t *testing.T) { + categoryName := "My category" + client := createClient(t) + + _, err := client.CreateCategory(categoryName) + if err != nil { + t.Fatal(err) + } + + categories, err := client.Categories() + if err != nil { + t.Fatal(err) + } + + if len(categories) != 2 { + t.Fatalf(`Invalid number of categories, got "%v" instead of "%v"`, len(categories), 2) + } + + if categories[0].ID == 0 { + t.Fatalf(`Invalid categoryID, got "%v"`, categories[0].ID) + } + + if categories[0].UserID <= 0 { + t.Fatalf(`Invalid userID, got "%v"`, categories[0].UserID) + } + + if categories[0].Title != "All" { + t.Fatalf(`Invalid title, got "%v" instead of "%v"`, categories[0].Title, "All") + } + + if categories[1].ID == 0 { + t.Fatalf(`Invalid categoryID, got "%v"`, categories[0].ID) + } + + if categories[1].UserID <= 0 { + t.Fatalf(`Invalid userID, got "%v"`, categories[1].UserID) + } + + if categories[1].Title != categoryName { + t.Fatalf(`Invalid title, got "%v" instead of "%v"`, categories[1].Title, categoryName) + } +} + +func TestDeleteCategory(t *testing.T) { + client := createClient(t) + + category, err := client.CreateCategory("My category") + if err != nil { + t.Fatal(err) + } + + err = client.DeleteCategory(category.ID) + if err != nil { + t.Fatal(`Removing a category should not raise any error`) + } +} + +func TestCannotDeleteCategoryOfAnotherUser(t *testing.T) { + client := createClient(t) + categories, err := client.Categories() + if err != nil { + t.Fatal(err) + } + + client = createClient(t) + err = client.DeleteCategory(categories[0].ID) + if err == nil { + t.Fatal(`Removing a category that belongs to another user should be forbidden`) + } +} diff --git a/tests/doc.go b/tests/doc.go new file mode 100644 index 00000000..be614d00 --- /dev/null +++ b/tests/doc.go @@ -0,0 +1,10 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the MIT license +// that can be found in the LICENSE file. + +/* + +Package tests contains API integration tests. + +*/ +package tests // import "miniflux.app/tests" diff --git a/tests/endpoint_test.go b/tests/endpoint_test.go new file mode 100644 index 00000000..f1ae94d3 --- /dev/null +++ b/tests/endpoint_test.go @@ -0,0 +1,21 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "testing" + + miniflux "miniflux.app/client" +) + +func TestWithBadEndpoint(t *testing.T) { + client := miniflux.New("bad url", testAdminUsername, testAdminPassword) + _, err := client.Users() + if err == nil { + t.Fatal(`Using a bad URL should raise an error`) + } +} diff --git a/tests/entry_test.go b/tests/entry_test.go new file mode 100644 index 00000000..369f5469 --- /dev/null +++ b/tests/entry_test.go @@ -0,0 +1,225 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "testing" + + miniflux "miniflux.app/client" +) + +func TestGetAllFeedEntries(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + allResults, err := client.FeedEntries(feed.ID, nil) + if err != nil { + t.Fatal(err) + } + + if allResults.Total == 0 { + t.Fatal(`Invalid number of entries`) + } + + if allResults.Entries[0].Title == "" { + t.Fatal(`Invalid entry title`) + } + + filteredResults, err := client.FeedEntries(feed.ID, &miniflux.Filter{Limit: 1, Offset: 5}) + if err != nil { + t.Fatal(err) + } + + if allResults.Total != filteredResults.Total { + t.Fatal(`Total should always contains the total number of items regardless of filters`) + } + + if allResults.Entries[0].ID == filteredResults.Entries[0].ID { + t.Fatal(`Filtered entries should be different than previous results`) + } + + filteredResultsByEntryID, err := client.FeedEntries(feed.ID, &miniflux.Filter{BeforeEntryID: allResults.Entries[0].ID}) + if err != nil { + t.Fatal(err) + } + + if filteredResultsByEntryID.Entries[0].ID == allResults.Entries[0].ID { + t.Fatal(`The first entry should filtered out`) + } +} + +func TestGetAllEntries(t *testing.T) { + client := createClient(t) + createFeed(t, client) + + resultWithoutSorting, err := client.Entries(nil) + if err != nil { + t.Fatal(err) + } + + if resultWithoutSorting.Total == 0 { + t.Fatal(`Invalid number of entries`) + } + + resultWithStatusFilter, err := client.Entries(&miniflux.Filter{Status: miniflux.EntryStatusRead}) + if err != nil { + t.Fatal(err) + } + + if resultWithStatusFilter.Total != 0 { + t.Fatal(`We should have 0 read entries`) + } + + resultWithDifferentSorting, err := client.Entries(&miniflux.Filter{Order: "published_at", Direction: "desc"}) + if err != nil { + t.Fatal(err) + } + + if resultWithDifferentSorting.Entries[0].Title == resultWithoutSorting.Entries[0].Title { + t.Fatalf(`The items should be sorted differently "%v" vs "%v"`, resultWithDifferentSorting.Entries[0].Title, resultWithoutSorting.Entries[0].Title) + } + + resultWithStarredEntries, err := client.Entries(&miniflux.Filter{Starred: true}) + if err != nil { + t.Fatal(err) + } + + if resultWithStarredEntries.Total != 0 { + t.Fatalf(`We are not supposed to have starred entries yet`) + } +} + +func TestSearchEntries(t *testing.T) { + client := createClient(t) + categories, err := client.Categories() + if err != nil { + t.Fatal(err) + } + + feedID, err := client.CreateFeed("https://github.com/miniflux/miniflux/releases.atom", categories[0].ID) + if err != nil { + t.Fatal(err) + } + + if feedID == 0 { + t.Fatalf(`Invalid feed ID, got %q`, feedID) + } + + results, err := client.Entries(&miniflux.Filter{Search: "2.0.8"}) + if err != nil { + t.Fatal(err) + } + + if results.Total != 1 { + t.Fatalf(`We should have only one entry instead of %d`, results.Total) + } +} + +func TestInvalidFilters(t *testing.T) { + client := createClient(t) + createFeed(t, client) + + _, err := client.Entries(&miniflux.Filter{Status: "invalid"}) + if err == nil { + t.Fatal(`Using invalid status should raise an error`) + } + + _, err = client.Entries(&miniflux.Filter{Direction: "invalid"}) + if err == nil { + t.Fatal(`Using invalid direction should raise an error`) + } + + _, err = client.Entries(&miniflux.Filter{Order: "invalid"}) + if err == nil { + t.Fatal(`Using invalid order should raise an error`) + } +} + +func TestGetEntry(t *testing.T) { + client := createClient(t) + createFeed(t, client) + + result, err := client.Entries(&miniflux.Filter{Limit: 1}) + if err != nil { + t.Fatal(err) + } + + entry, err := client.FeedEntry(result.Entries[0].FeedID, result.Entries[0].ID) + if err != nil { + t.Fatal(err) + } + + if entry.ID != result.Entries[0].ID { + t.Fatal("Wrong entry returned") + } + + entry, err = client.Entry(result.Entries[0].ID) + if err != nil { + t.Fatal(err) + } + + if entry.ID != result.Entries[0].ID { + t.Fatal("Wrong entry returned") + } +} + +func TestUpdateStatus(t *testing.T) { + client := createClient(t) + createFeed(t, client) + + result, err := client.Entries(&miniflux.Filter{Limit: 1}) + if err != nil { + t.Fatal(err) + } + + err = client.UpdateEntries([]int64{result.Entries[0].ID}, miniflux.EntryStatusRead) + if err != nil { + t.Fatal(err) + } + + entry, err := client.Entry(result.Entries[0].ID) + if err != nil { + t.Fatal(err) + } + + if entry.Status != miniflux.EntryStatusRead { + t.Fatal("The entry status should be updated") + } + + err = client.UpdateEntries([]int64{result.Entries[0].ID}, "invalid") + if err == nil { + t.Fatal(`Invalid entry status should ne be accepted`) + } +} + +func TestToggleBookmark(t *testing.T) { + client := createClient(t) + createFeed(t, client) + + result, err := client.Entries(&miniflux.Filter{Limit: 1}) + if err != nil { + t.Fatal(err) + } + + if result.Entries[0].Starred { + t.Fatal("The entry should not be starred") + } + + err = client.ToggleBookmark(result.Entries[0].ID) + if err != nil { + t.Fatal(err) + } + + entry, err := client.Entry(result.Entries[0].ID) + if err != nil { + t.Fatal(err) + } + + if !entry.Starred { + t.Fatal("The entry should be starred") + } +} diff --git a/tests/feed_test.go b/tests/feed_test.go new file mode 100644 index 00000000..c9308266 --- /dev/null +++ b/tests/feed_test.go @@ -0,0 +1,390 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "strings" + "testing" + + miniflux "miniflux.app/client" +) + +func TestCreateFeed(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + if feed.ID == 0 { + t.Fatalf(`Invalid feed ID, got %q`, feed.ID) + } +} + +func TestCannotCreateDuplicatedFeed(t *testing.T) { + client := createClient(t) + feed, category := createFeed(t, client) + + _, err := client.CreateFeed(feed.FeedURL, category.ID) + if err == nil { + t.Fatal(`Duplicated feeds should not be allowed`) + } +} + +func TestCreateFeedWithInexistingCategory(t *testing.T) { + client := createClient(t) + + _, err := client.CreateFeed(testFeedURL, -1) + if err == nil { + t.Fatal(`Feeds should not be created with inexisting category`) + } +} + +func TestUpdateFeedURL(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + url := "test" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{FeedURL: &url}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.FeedURL != url { + t.Fatalf(`Wrong FeedURL, got %q instead of %q`, updatedFeed.FeedURL, url) + } + + url = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{FeedURL: &url}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.FeedURL == "" { + t.Fatalf(`The FeedURL should not be empty`) + } +} + +func TestUpdateFeedSiteURL(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + url := "test" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{SiteURL: &url}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.SiteURL != url { + t.Fatalf(`Wrong SiteURL, got %q instead of %q`, updatedFeed.SiteURL, url) + } + + url = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{SiteURL: &url}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.SiteURL == "" { + t.Fatalf(`The SiteURL should not be empty`) + } +} + +func TestUpdateFeedTitle(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + newTitle := "My new feed" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Title: &newTitle}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Title != newTitle { + t.Fatalf(`Wrong title, got %q instead of %q`, updatedFeed.Title, newTitle) + } + + newTitle = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Title: &newTitle}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Title == "" { + t.Fatalf(`The Title should not be empty`) + } +} + +func TestUpdateFeedCrawler(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + crawler := true + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Crawler: &crawler}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Crawler != crawler { + t.Fatalf(`Wrong crawler value, got "%v" instead of "%v"`, updatedFeed.Crawler, crawler) + } + + if updatedFeed.Title != feed.Title { + t.Fatalf(`The titles should be the same after update`) + } + + crawler = false + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Crawler: &crawler}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Crawler != crawler { + t.Fatalf(`Wrong crawler value, got "%v" instead of "%v"`, updatedFeed.Crawler, crawler) + } +} + +func TestUpdateFeedScraperRules(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + scraperRules := "test" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{ScraperRules: &scraperRules}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.ScraperRules != scraperRules { + t.Fatalf(`Wrong ScraperRules value, got "%v" instead of "%v"`, updatedFeed.ScraperRules, scraperRules) + } + + scraperRules = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{ScraperRules: &scraperRules}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.ScraperRules != scraperRules { + t.Fatalf(`Wrong ScraperRules value, got "%v" instead of "%v"`, updatedFeed.ScraperRules, scraperRules) + } +} + +func TestUpdateFeedRewriteRules(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + rewriteRules := "test" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{RewriteRules: &rewriteRules}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.RewriteRules != rewriteRules { + t.Fatalf(`Wrong RewriteRules value, got "%v" instead of "%v"`, updatedFeed.RewriteRules, rewriteRules) + } + + rewriteRules = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{RewriteRules: &rewriteRules}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.RewriteRules != rewriteRules { + t.Fatalf(`Wrong RewriteRules value, got "%v" instead of "%v"`, updatedFeed.RewriteRules, rewriteRules) + } +} + +func TestUpdateFeedUsername(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + username := "test" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Username: &username}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Username != username { + t.Fatalf(`Wrong Username value, got "%v" instead of "%v"`, updatedFeed.Username, username) + } + + username = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Username: &username}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Username != username { + t.Fatalf(`Wrong Username value, got "%v" instead of "%v"`, updatedFeed.Username, username) + } +} + +func TestUpdateFeedPassword(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + password := "test" + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{Password: &password}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Password != password { + t.Fatalf(`Wrong Password value, got "%v" instead of "%v"`, updatedFeed.Password, password) + } + + password = "" + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{Password: &password}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Password != password { + t.Fatalf(`Wrong Password value, got "%v" instead of "%v"`, updatedFeed.Password, password) + } +} + +func TestUpdateFeedCategory(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + + newCategory, err := client.CreateCategory("my new category") + if err != nil { + t.Fatal(err) + } + + updatedFeed, err := client.UpdateFeed(feed.ID, &miniflux.FeedModification{CategoryID: &newCategory.ID}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Category.ID != newCategory.ID { + t.Fatalf(`Wrong CategoryID value, got "%v" instead of "%v"`, updatedFeed.Category.ID, newCategory.ID) + } + + categoryID := int64(0) + updatedFeed, err = client.UpdateFeed(feed.ID, &miniflux.FeedModification{CategoryID: &categoryID}) + if err != nil { + t.Fatal(err) + } + + if updatedFeed.Category.ID == 0 { + t.Fatalf(`The CategoryID must defined`) + } +} + +func TestDeleteFeed(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + if err := client.DeleteFeed(feed.ID); err != nil { + t.Fatal(err) + } +} + +func TestRefreshFeed(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + if err := client.RefreshFeed(feed.ID); err != nil { + t.Fatal(err) + } +} + +func TestGetFeed(t *testing.T) { + client := createClient(t) + feed, category := createFeed(t, client) + + if feed.Title != testFeedTitle { + t.Fatalf(`Invalid feed title, got "%v" instead of "%v"`, feed.Title, testFeedTitle) + } + + if feed.SiteURL != testWebsiteURL { + t.Fatalf(`Invalid site URL, got "%v" instead of "%v"`, feed.SiteURL, testWebsiteURL) + } + + if feed.FeedURL != testFeedURL { + t.Fatalf(`Invalid feed URL, got "%v" instead of "%v"`, feed.FeedURL, testFeedURL) + } + + if feed.Category.ID != category.ID { + t.Fatalf(`Invalid feed category ID, got "%v" instead of "%v"`, feed.Category.ID, category.ID) + } + + if feed.Category.UserID != category.UserID { + t.Fatalf(`Invalid feed category user ID, got "%v" instead of "%v"`, feed.Category.UserID, category.UserID) + } + + if feed.Category.Title != category.Title { + t.Fatalf(`Invalid feed category title, got "%v" instead of "%v"`, feed.Category.Title, category.Title) + } +} + +func TestGetFeedIcon(t *testing.T) { + client := createClient(t) + feed, _ := createFeed(t, client) + feedIcon, err := client.FeedIcon(feed.ID) + if err != nil { + t.Fatal(err) + } + + if feedIcon.ID == 0 { + t.Fatalf(`Invalid feed icon ID, got "%v"`, feedIcon.ID) + } + + if feedIcon.MimeType != "image/x-icon" { + t.Fatalf(`Invalid feed icon mime type, got "%v" instead of "%v"`, feedIcon.MimeType, "image/x-icon") + } + + if !strings.Contains(feedIcon.Data, "image/x-icon") { + t.Fatalf(`Invalid feed icon data, got "%v"`, feedIcon.Data) + } +} + +func TestGetFeedIconNotFound(t *testing.T) { + client := createClient(t) + if _, err := client.FeedIcon(42); err == nil { + t.Fatalf(`The feed icon should be null`) + } +} + +func TestGetFeeds(t *testing.T) { + client := createClient(t) + feed, category := createFeed(t, client) + + feeds, err := client.Feeds() + if err != nil { + t.Fatal(err) + } + + if len(feeds) != 1 { + t.Fatalf(`Invalid number of feeds`) + } + + if feeds[0].ID != feed.ID { + t.Fatalf(`Invalid feed ID, got "%v" instead of "%v"`, feeds[0].ID, feed.ID) + } + + if feeds[0].Title != testFeedTitle { + t.Fatalf(`Invalid feed title, got "%v" instead of "%v"`, feeds[0].Title, testFeedTitle) + } + + if feeds[0].SiteURL != testWebsiteURL { + t.Fatalf(`Invalid site URL, got "%v" instead of "%v"`, feeds[0].SiteURL, testWebsiteURL) + } + + if feeds[0].FeedURL != testFeedURL { + t.Fatalf(`Invalid feed URL, got "%v" instead of "%v"`, feeds[0].FeedURL, testFeedURL) + } + + if feeds[0].Category.ID != category.ID { + t.Fatalf(`Invalid feed category ID, got "%v" instead of "%v"`, feeds[0].Category.ID, category.ID) + } + + if feeds[0].Category.UserID != category.UserID { + t.Fatalf(`Invalid feed category user ID, got "%v" instead of "%v"`, feeds[0].Category.UserID, category.UserID) + } + + if feeds[0].Category.Title != category.Title { + t.Fatalf(`Invalid feed category title, got "%v" instead of "%v"`, feeds[0].Category.Title, category.Title) + } +} diff --git a/tests/import_export_test.go b/tests/import_export_test.go new file mode 100644 index 00000000..60114757 --- /dev/null +++ b/tests/import_export_test.go @@ -0,0 +1,46 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "bytes" + "io/ioutil" + "strings" + "testing" +) + +func TestExport(t *testing.T) { + client := createClient(t) + + output, err := client.Export() + if err != nil { + t.Fatal(err) + } + + if !strings.HasPrefix(string(output), " + + + + + + + ` + + b := bytes.NewReader([]byte(data)) + err := client.Import(ioutil.NopCloser(b)) + if err != nil { + t.Fatal(err) + } +} diff --git a/tests/subscription_test.go b/tests/subscription_test.go new file mode 100644 index 00000000..5d98cc40 --- /dev/null +++ b/tests/subscription_test.go @@ -0,0 +1,35 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "testing" +) + +func TestDiscoverSubscriptions(t *testing.T) { + client := createClient(t) + subscriptions, err := client.Discover(testWebsiteURL) + if err != nil { + t.Fatal(err) + } + + if len(subscriptions) != 1 { + t.Fatalf(`Invalid number of subscriptions, got "%v" instead of "%v"`, len(subscriptions), 2) + } + + if subscriptions[0].Title != testFeedTitle { + t.Fatalf(`Invalid feed title, got "%v" instead of "%v"`, subscriptions[0].Title, testFeedTitle) + } + + if subscriptions[0].Type != "atom" { + t.Fatalf(`Invalid feed type, got "%v" instead of "%v"`, subscriptions[0].Type, "atom") + } + + if subscriptions[0].URL != testFeedURL { + t.Fatalf(`Invalid feed URL, got "%v" instead of "%v"`, subscriptions[0].URL, testFeedURL) + } +} diff --git a/tests/tests.go b/tests/tests.go new file mode 100644 index 00000000..8183327c --- /dev/null +++ b/tests/tests.go @@ -0,0 +1,68 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package tests + +import ( + "math/rand" + "strconv" + "strings" + "testing" + "time" + + miniflux "miniflux.app/client" +) + +const ( + testBaseURL = "http://127.0.0.1:8080/" + testAdminUsername = "admin" + testAdminPassword = "test123" + testStandardPassword = "secret" + testFeedURL = "https://github.com/miniflux/miniflux/commits/master.atom" + testFeedTitle = "Recent Commits to miniflux:master" + testWebsiteURL = "https://github.com/miniflux/miniflux/commits/master" +) + +func getRandomUsername() string { + rand.Seed(time.Now().UnixNano()) + var suffix []string + for i := 0; i < 10; i++ { + suffix = append(suffix, strconv.Itoa(rand.Intn(1000))) + } + return "user" + strings.Join(suffix, "") +} + +func createClient(t *testing.T) *miniflux.Client { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + _, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + return miniflux.New(testBaseURL, username, testStandardPassword) +} + +func createFeed(t *testing.T, client *miniflux.Client) (*miniflux.Feed, *miniflux.Category) { + categories, err := client.Categories() + if err != nil { + t.Fatal(err) + } + + feedID, err := client.CreateFeed(testFeedURL, categories[0].ID) + if err != nil { + t.Fatal(err) + } + + if feedID == 0 { + t.Fatalf(`Invalid feed ID, got %q`, feedID) + } + + feed, err := client.Feed(feedID) + if err != nil { + t.Fatal(err) + } + + return feed, categories[0] +} diff --git a/tests/user_test.go b/tests/user_test.go new file mode 100644 index 00000000..85b6ebd2 --- /dev/null +++ b/tests/user_test.go @@ -0,0 +1,380 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build integration + +package tests + +import ( + "testing" + + miniflux "miniflux.app/client" +) + +func TestWithWrongCredentials(t *testing.T) { + client := miniflux.New(testBaseURL, "invalid", "invalid") + _, err := client.Users() + if err == nil { + t.Fatal(`Using bad credentials should raise an error`) + } + + if err != miniflux.ErrNotAuthorized { + t.Fatal(`A "Not Authorized" error should be raised`) + } +} + +func TestGetCurrentLoggedUser(t *testing.T) { + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.Me() + if err != nil { + t.Fatal(err) + } + + if user.ID == 0 { + t.Fatalf(`Invalid userID, got %q`, user.ID) + } + + if user.Username != testAdminUsername { + t.Fatalf(`Invalid username, got %q`, user.Username) + } +} + +func TestGetUsers(t *testing.T) { + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + users, err := client.Users() + if err != nil { + t.Fatal(err) + } + + if len(users) == 0 { + t.Fatal("The list of users is empty") + } + + if users[0].ID == 0 { + t.Fatalf(`Invalid userID, got "%v"`, users[0].ID) + } + + if users[0].Username != testAdminUsername { + t.Fatalf(`Invalid username, got "%v" instead of "%v"`, users[0].Username, testAdminUsername) + } + + if users[0].Password != "" { + t.Fatalf(`Invalid password, got "%v"`, users[0].Password) + } + + if users[0].Language != "en_US" { + t.Fatalf(`Invalid language, got "%v"`, users[0].Language) + } + + if users[0].Theme != "default" { + t.Fatalf(`Invalid theme, got "%v"`, users[0].Theme) + } + + if users[0].Timezone != "UTC" { + t.Fatalf(`Invalid timezone, got "%v"`, users[0].Timezone) + } + + if !users[0].IsAdmin { + t.Fatalf(`Invalid role, got "%v"`, users[0].IsAdmin) + } +} + +func TestCreateStandardUser(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + if user.ID == 0 { + t.Fatalf(`Invalid userID, got "%v"`, user.ID) + } + + if user.Username != username { + t.Fatalf(`Invalid username, got "%v" instead of "%v"`, user.Username, username) + } + + if user.Password != "" { + t.Fatalf(`Invalid password, got "%v"`, user.Password) + } + + if user.Language != "en_US" { + t.Fatalf(`Invalid language, got "%v"`, user.Language) + } + + if user.Theme != "default" { + t.Fatalf(`Invalid theme, got "%v"`, user.Theme) + } + + if user.Timezone != "UTC" { + t.Fatalf(`Invalid timezone, got "%v"`, user.Timezone) + } + + if user.IsAdmin { + t.Fatalf(`Invalid role, got "%v"`, user.IsAdmin) + } + + if user.LastLoginAt != nil { + t.Fatalf(`Invalid last login date, got "%v"`, user.LastLoginAt) + } +} + +func TestRemoveUser(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + if err := client.DeleteUser(user.ID); err != nil { + t.Fatalf(`Unable to remove user: "%v"`, err) + } +} + +func TestGetUserByID(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + _, err = client.UserByID(99999) + if err == nil { + t.Fatal(`Should returns a 404`) + } + + user, err = client.UserByID(user.ID) + if err != nil { + t.Fatal(err) + } + + if user.ID == 0 { + t.Fatalf(`Invalid userID, got "%v"`, user.ID) + } + + if user.Username != username { + t.Fatalf(`Invalid username, got "%v" instead of "%v"`, user.Username, username) + } + + if user.Password != "" { + t.Fatalf(`Invalid password, got "%v"`, user.Password) + } + + if user.Language != "en_US" { + t.Fatalf(`Invalid language, got "%v"`, user.Language) + } + + if user.Theme != "default" { + t.Fatalf(`Invalid theme, got "%v"`, user.Theme) + } + + if user.Timezone != "UTC" { + t.Fatalf(`Invalid timezone, got "%v"`, user.Timezone) + } + + if user.IsAdmin { + t.Fatalf(`Invalid role, got "%v"`, user.IsAdmin) + } + + if user.LastLoginAt != nil { + t.Fatalf(`Invalid last login date, got "%v"`, user.LastLoginAt) + } +} + +func TestGetUserByUsername(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + _, err = client.UserByUsername("missinguser") + if err == nil { + t.Fatal(`Should returns a 404`) + } + + user, err = client.UserByUsername(username) + if err != nil { + t.Fatal(err) + } + + if user.ID == 0 { + t.Fatalf(`Invalid userID, got "%v"`, user.ID) + } + + if user.Username != username { + t.Fatalf(`Invalid username, got "%v" instead of "%v"`, user.Username, username) + } + + if user.Password != "" { + t.Fatalf(`Invalid password, got "%v"`, user.Password) + } + + if user.Language != "en_US" { + t.Fatalf(`Invalid language, got "%v"`, user.Language) + } + + if user.Theme != "default" { + t.Fatalf(`Invalid theme, got "%v"`, user.Theme) + } + + if user.Timezone != "UTC" { + t.Fatalf(`Invalid timezone, got "%v"`, user.Timezone) + } + + if user.IsAdmin { + t.Fatalf(`Invalid role, got "%v"`, user.IsAdmin) + } + + if user.LastLoginAt != nil { + t.Fatalf(`Invalid last login date, got "%v"`, user.LastLoginAt) + } +} + +func TestUpdateUserTheme(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + theme := "black" + user, err = client.UpdateUser(user.ID, &miniflux.UserModification{Theme: &theme}) + if err != nil { + t.Fatal(err) + } + + if user.Theme != theme { + t.Fatalf(`Unable to update user Theme: got "%v" instead of "%v"`, user.Theme, theme) + } +} + +func TestUpdateUserThemeWithInvalidValue(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + theme := "something that doesn't exists" + _, err = client.UpdateUser(user.ID, &miniflux.UserModification{Theme: &theme}) + if err == nil { + t.Fatal(`Updating a user Theme with an invalid value should raise an error`) + } +} + +func TestCannotCreateDuplicateUser(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + _, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + _, err = client.CreateUser(username, testStandardPassword, false) + if err == nil { + t.Fatal(`Duplicate users should not be allowed`) + } +} + +func TestCannotListUsersAsNonAdmin(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + _, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + client = miniflux.New(testBaseURL, username, testStandardPassword) + _, err = client.Users() + if err == nil { + t.Fatal(`Standard users should not be able to list any users`) + } + + if err != miniflux.ErrForbidden { + t.Fatal(`A "Forbidden" error should be raised`) + } +} + +func TestCannotGetUserAsNonAdmin(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + client = miniflux.New(testBaseURL, username, testStandardPassword) + _, err = client.UserByID(user.ID) + if err == nil { + t.Fatal(`Standard users should not be able to get any users`) + } + + if err != miniflux.ErrForbidden { + t.Fatal(`A "Forbidden" error should be raised`) + } +} + +func TestCannotUpdateUserAsNonAdmin(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + client = miniflux.New(testBaseURL, username, testStandardPassword) + _, err = client.UpdateUser(user.ID, &miniflux.UserModification{}) + if err == nil { + t.Fatal(`Standard users should not be able to update any users`) + } + + if err != miniflux.ErrForbidden { + t.Fatal(`A "Forbidden" error should be raised`) + } +} + +func TestCannotCreateUserAsNonAdmin(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + _, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + client = miniflux.New(testBaseURL, username, testStandardPassword) + _, err = client.CreateUser(username, testStandardPassword, false) + if err == nil { + t.Fatal(`Standard users should not be able to create users`) + } + + if err != miniflux.ErrForbidden { + t.Fatal(`A "Forbidden" error should be raised`) + } +} + +func TestCannotDeleteUserAsNonAdmin(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + client = miniflux.New(testBaseURL, username, testStandardPassword) + err = client.DeleteUser(user.ID) + if err == nil { + t.Fatal(`Standard users should not be able to remove any users`) + } + + if err != miniflux.ErrForbidden { + t.Fatal(`A "Forbidden" error should be raised`) + } +}