Skip to content

Commit

Permalink
feat(server): created joke server
Browse files Browse the repository at this point in the history
  • Loading branch information
Wittano committed May 30, 2024
1 parent ee3599f commit 8aec53c
Show file tree
Hide file tree
Showing 22 changed files with 597 additions and 214 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ tui: protobuf

protobuf:
mkdir -p $(PROTOBUF_API_DEST)
protoc --go_out=. ./proto/*
protoc --go_out=./api --go_opt=paths=source_relative --go-grpc_out=./api --go-grpc_opt=paths=source_relative proto/*

test: protobuf
go test -race ./...
find . -name go.mod -execdir go test ./... \;

all: bot-dev bot-prod sever tui test
all: bot-prod sever tui test

# FIXME Replaced invalid path
install: prod test
Expand Down
13 changes: 7 additions & 6 deletions bot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/wittano/komputer/bot/log"
"github.com/wittano/komputer/bot/voice"
"github.com/wittano/komputer/db"
dbJoke "github.com/wittano/komputer/db/joke"
"log/slog"
"time"
)
Expand All @@ -34,7 +35,7 @@ func (sc slashCommandHandler) handleSlashCommand(s *discordgo.Session, i *discor
requestID := uuid.New().String()
loggerCtx := log.NewContext(requestID)
deadlineCtx, cancel := context.WithTimeout(loggerCtx, cmdTimeout)
ctx := context.WithValue(deadlineCtx, joke.GuildIDKey, i.GuildID)
ctx := context.WithValue(deadlineCtx, dbJoke.GuildIDKey, i.GuildID)
defer cancel()

userID := i.Member.User.ID
Expand Down Expand Up @@ -123,8 +124,8 @@ func (d *DiscordBot) Close() (err error) {
return
}

func createJokeGetServices(globalCtx context.Context, database *db.MongodbDatabase) []joke.SearchService {
return []joke.SearchService{
func createJokeGetServices(globalCtx context.Context, database *db.MongodbDatabase) []dbJoke.SearchService {
return []dbJoke.SearchService{
jokeDevServiceID: joke.NewJokeDevService(globalCtx),
humorAPIServiceID: joke.NewHumorAPIService(globalCtx),
databaseServiceID: joke.NewDatabaseJokeService(database),
Expand All @@ -133,12 +134,12 @@ func createJokeGetServices(globalCtx context.Context, database *db.MongodbDataba

func createCommands(
globalCtx context.Context,
services []joke.SearchService,
services []dbJoke.SearchService,
spockVoice map[string]chan struct{},
guildVoiceChats map[string]voice.ChatInfo,
) map[string]command.DiscordSlashCommandHandler {
welcome := command.WelcomeCommand{}
addJoke := command.AddJokeCommand{Service: services[databaseServiceID].(joke.DatabaseService)}
addJoke := command.AddJokeCommand{Service: services[databaseServiceID].(dbJoke.Database)}
getJoke := command.JokeCommand{Services: services}
spock := command.SpockCommand{
GlobalCtx: globalCtx,
Expand All @@ -159,7 +160,7 @@ func createCommands(
}

func createOptions(
services []joke.SearchService,
services []dbJoke.SearchService,
commands map[string]command.DiscordSlashCommandHandler,
) []command.DiscordEventHandler {
apologies := command.ApologiesOption{}
Expand Down
18 changes: 9 additions & 9 deletions bot/command/joke.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"errors"
"fmt"
"github.com/bwmarrin/discordgo"
"github.com/wittano/komputer/bot/joke"
"github.com/wittano/komputer/bot/log"
"github.com/wittano/komputer/db/joke"
"go.mongodb.org/mongo-driver/bson/primitive"
"log/slog"
"math/rand"
Expand Down Expand Up @@ -48,7 +48,7 @@ func (j JokeCommand) Command() *discordgo.ApplicationCommand {
jokeTypeOption(false),
{
Name: idOptionKey,
Description: "Joke ID",
Description: "Jokes ID",
Type: discordgo.ApplicationCommandOptionString,
Required: false,
},
Expand All @@ -73,7 +73,7 @@ findJoke:
return nil, DiscordError{err, "Nie udało mi się, znaleść żadnego żartu"}
}

res, err := service.Joke(ctx, searchQuery)
res, err := service.RandomJoke(ctx, searchQuery)
if err != nil {
loggerCtx.Logger.Error(err.Error())
goto findJoke
Expand Down Expand Up @@ -137,7 +137,7 @@ func jokeCategoryOption(required bool) *discordgo.ApplicationCommandOption {
return &discordgo.ApplicationCommandOption{
Type: discordgo.ApplicationCommandOptionString,
Name: categoryOptionKey,
Description: "Joke category",
Description: "Jokes category",
Required: required,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Expand All @@ -164,7 +164,7 @@ func jokeTypeOption(required bool) *discordgo.ApplicationCommandOption {
return &discordgo.ApplicationCommandOption{
Type: discordgo.ApplicationCommandOptionString,
Name: typeOptionKey,
Description: "Type of joke",
Description: "RawType of joke",
Required: required,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Expand Down Expand Up @@ -200,7 +200,7 @@ func (j discordJoke) singleTypeJoke() (msg *discordgo.InteractionResponseData) {
embeds := []*discordgo.MessageEmbed{
{
Type: discordgo.EmbedTypeRich,
Title: "Joke",
Title: "Jokes",
Description: j.joke.Answer,
Color: 0x02f5f5,
Author: &discordgo.MessageEmbedAuthor{
Expand Down Expand Up @@ -234,7 +234,7 @@ func (j discordJoke) twoPartJoke() *discordgo.InteractionResponseData {
embeds := []*discordgo.MessageEmbed{
{
Type: discordgo.EmbedTypeRich,
Title: "Joke",
Title: "Jokes",
Color: 0x02f5f5,
Author: &discordgo.MessageEmbedAuthor{
Name: "komputer",
Expand Down Expand Up @@ -382,7 +382,7 @@ func (n NextJokeOption) Execute(ctx context.Context, _ *discordgo.Session, i *di
return nil, err
}

res, err := service.Joke(ctx, joke.SearchParams{Type: randJokeType()})
res, err := service.RandomJoke(ctx, joke.SearchParams{Type: randJokeType()})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -416,7 +416,7 @@ func (s SameJokeCategoryOption) Execute(ctx context.Context, _ *discordgo.Sessio
return nil, err
}

res, err := service.Joke(ctx, joke.SearchParams{Type: randJokeType(), Category: category})
res, err := service.RandomJoke(ctx, joke.SearchParams{Type: randJokeType(), Category: category})
if err != nil {
return nil, err
}
Expand Down
7 changes: 4 additions & 3 deletions bot/command/joke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"github.com/wittano/komputer/bot/joke"
dbJoke "github.com/wittano/komputer/db/joke"
"go.mongodb.org/mongo-driver/mongo"
"testing"
)
Expand All @@ -20,7 +21,7 @@ func (d dumpMongoService) Client(_ context.Context) (*mongo.Client, error) {

func TestSelectGetService(t *testing.T) {
ctx := context.Background()
testServices := []joke.SearchService{
testServices := []dbJoke.SearchService{
joke.NewJokeDevService(ctx),
joke.NewHumorAPIService(ctx),
joke.NewDatabaseJokeService(dumpMongoService{}),
Expand All @@ -43,7 +44,7 @@ func TestSelectGetService(t *testing.T) {
func TestFindJokeService_ContextCancelled(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
testServices := []joke.SearchService{
testServices := []dbJoke.SearchService{
joke.NewJokeDevService(ctx),
joke.NewHumorAPIService(ctx),
joke.NewDatabaseJokeService(dumpMongoService{}),
Expand All @@ -56,7 +57,7 @@ func TestFindJokeService_ContextCancelled(t *testing.T) {

func TestFindJokeService_ServicesIsDeactivated(t *testing.T) {
ctx := context.Background()
services := []joke.SearchService{
services := []dbJoke.SearchService{
joke.NewDatabaseJokeService(dumpMongoService{}),
}

Expand Down
43 changes: 22 additions & 21 deletions bot/joke/humorapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"github.com/wittano/komputer/bot/log"
"github.com/wittano/komputer/db/joke"
"io"
"log/slog"
"net/http"
Expand Down Expand Up @@ -43,33 +44,33 @@ func (h HumorAPIService) Active(ctx context.Context) (active bool) {
return
}

func (h *HumorAPIService) Joke(ctx context.Context, search SearchParams) (Joke, error) {
func (h *HumorAPIService) RandomJoke(ctx context.Context, search joke.SearchParams) (joke.Joke, error) {
select {
case <-ctx.Done():
return Joke{}, context.Canceled
return joke.Joke{}, context.Canceled
default:
}

if !h.Active(ctx) {
return Joke{}, HumorAPILimitExceededErr
return joke.Joke{}, HumorAPILimitExceededErr
}

apiKey, ok := os.LookupEnv(humorAPIKey)
if !ok {
return Joke{}, errors.New("humorAPI: missing " + humorAPIKey)
return joke.Joke{}, errors.New("humorAPI: missing " + humorAPIKey)
}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, humorApiURL+humorAPICategory(search.Category), nil)
if err != nil {
return Joke{}, err
return joke.Joke{}, err
}

req.Header["X-RapidAPI-Key"] = []string{apiKey}
req.Header["X-RapidAPI-Host"] = []string{"humor-jokes-and-memes.p.rapidapi.com"}

res, err := h.client.Do(req)
if err != nil {
return Joke{}, err
return joke.Joke{}, err
}
defer res.Body.Close()

Expand All @@ -81,7 +82,7 @@ func (h *HumorAPIService) Joke(ctx context.Context, search SearchParams) (Joke,

go unlockService(h.globalCtx, &h.active, resetTime)

return Joke{}, HumorAPILimitExceededErr
return joke.Joke{}, HumorAPILimitExceededErr
} else if res.StatusCode != http.StatusOK {
msg, err := io.ReadAll(res.Body)
if err != nil {
Expand All @@ -91,41 +92,41 @@ func (h *HumorAPIService) Joke(ctx context.Context, search SearchParams) (Joke,
msg = []byte{}
}

return Joke{}, fmt.Errorf("humorAPI: failed to get joke. status '%d', msg: '%s'", res.StatusCode, msg)
return joke.Joke{}, fmt.Errorf("humorAPI: failed to get joke. status '%d', msg: '%s'", res.StatusCode, msg)
}

select {
case <-ctx.Done():
return Joke{}, context.Canceled
return joke.Joke{}, context.Canceled
default:
}

resBody, err := io.ReadAll(res.Body)
if err != nil {
return Joke{}, err
return joke.Joke{}, err
}

var joke humorAPIResponse
if err = json.Unmarshal(resBody, &joke); err != nil {
return Joke{}, err
var humorRes humorAPIResponse
if err = json.Unmarshal(resBody, &humorRes); err != nil {
return joke.Joke{}, err
}

return Joke{
return joke.Joke{
Category: search.Category,
Type: Single,
Answer: joke.Content,
Type: joke.Single,
Answer: humorRes.Content,
}, nil
}

func humorAPICategory(category Category) (res string) {
func humorAPICategory(category joke.Category) (res string) {
switch category {
case PROGRAMMING:
case joke.PROGRAMMING:
res = "nerdy"
case DARK:
case joke.DARK:
res = "dark"
case YOMAMA:
case joke.YOMAMA:
res = "yo_mama"
case Any:
case joke.Any:
default:
res = "one_liner"
}
Expand Down
27 changes: 21 additions & 6 deletions bot/joke/humorapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,27 @@ import (
"encoding/json"
"errors"
"github.com/jarcoal/httpmock"
"github.com/wittano/komputer/db/joke"
"net/http"
"os"
"strconv"
"testing"
)

var (
testParams = joke.SearchParams{
Type: joke.Single,
Category: joke.Any,
}
testJoke = joke.Joke{
Question: "testQuestion",
Answer: "testAnswer",
Type: joke.Single,
Category: joke.Any,
GuildID: "",
}
)

var testHumorAPIResponse = humorAPIResponse{
Content: "testJokeRes",
ID: 213,
Expand All @@ -36,7 +51,7 @@ func TestHumorAPIService_Get(t *testing.T) {
ctx := context.Background()
service := NewHumorAPIService(ctx)

joke, err := service.Joke(ctx, testParams)
joke, err := service.RandomJoke(ctx, testParams)
if err != nil {
t.Fatal(err)
}
Expand All @@ -53,7 +68,7 @@ func TestHumorAPIService_Get(t *testing.T) {
func TestHumorAPIService_GetWithMissingApiKey(t *testing.T) {
ctx := context.Background()
service := NewHumorAPIService(ctx)
if _, err := service.Joke(ctx, testParams); err == nil {
if _, err := service.RandomJoke(ctx, testParams); err == nil {
t.Fatal("service found API key, but it didn't set")
}
}
Expand All @@ -79,7 +94,7 @@ func TestHumorAPIService_GetWithApiReturnInvalidStatus(t *testing.T) {

service := NewHumorAPIService(ctx)

if _, err := service.Joke(ctx, testParams); err == nil {
if _, err := service.RandomJoke(ctx, testParams); err == nil {
t.Fatal("service didn't handle correct a bad/invalid http status")
}
})
Expand All @@ -101,7 +116,7 @@ func TestHumorAPIService_GetWithApiLimitExceeded(t *testing.T) {
ctx := context.Background()
service := NewHumorAPIService(ctx)

if _, err := service.Joke(ctx, testParams); !errors.Is(err, HumorAPILimitExceededErr) {
if _, err := service.RandomJoke(ctx, testParams); !errors.Is(err, HumorAPILimitExceededErr) {
t.Fatal(err)
}
}
Expand All @@ -123,11 +138,11 @@ func TestHumorAPIService_Active(t *testing.T) {

service := NewHumorAPIService(ctx)

if _, err := service.Joke(ctx, testParams); !errors.Is(err, HumorAPILimitExceededErr) {
if _, err := service.RandomJoke(ctx, testParams); !errors.Is(err, HumorAPILimitExceededErr) {
t.Fatal(err)
}

if _, err := service.Joke(ctx, testParams); !errors.Is(err, HumorAPILimitExceededErr) {
if _, err := service.RandomJoke(ctx, testParams); !errors.Is(err, HumorAPILimitExceededErr) {
t.Fatal(err)
}

Expand Down
Loading

0 comments on commit 8aec53c

Please sign in to comment.