Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
crud_test.go6.02 kB
package library_test import ( "context" "net/http" "testing" "github.com/google/uuid" "github.com/oapi-codegen/nullable" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/fx" "github.com/Southclaws/storyden/app/resources/account/account_writer" "github.com/Southclaws/storyden/app/resources/seed" "github.com/Southclaws/storyden/app/transports/http/openapi" "github.com/Southclaws/storyden/internal/integration" "github.com/Southclaws/storyden/internal/integration/e2e" "github.com/Southclaws/storyden/tests" ) func TestNodesHappyPath(t *testing.T) { t.Parallel() integration.Test(t, nil, e2e.Setup(), fx.Invoke(func( lc fx.Lifecycle, ctx context.Context, cl *openapi.ClientWithResponses, sh *e2e.SessionHelper, aw *account_writer.Writer, ) { lc.Append(fx.StartHook(func() { a := assert.New(t) r := require.New(t) ctx, acc := e2e.WithAccount(ctx, aw, seed.Account_001_Odin) visibility := openapi.Published name1 := "test-node-1" slug1 := name1 + uuid.NewString() content1 := "<h1>Nodes</h1><p>Rich text content.</p>" url1 := "https://southcla.ws" node1, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{ Name: name1, Slug: &slug1, Content: &content1, Url: &url1, Visibility: &visibility, // Admin account can post directly to published }, sh.WithSession(ctx)) tests.Ok(t, err, node1) a.Equal(name1, node1.JSON200.Name) a.Equal(slug1, node1.JSON200.Slug) a.Equal("Rich text content.", node1.JSON200.Description) a.Equal("<body><h1>Nodes</h1><p>Rich text content.</p></body>", *node1.JSON200.Content) r.NotNil(node1.JSON200.Link) a.Equal(url1, node1.JSON200.Link.Url) a.Equal(acc.ID.String(), string(node1.JSON200.Owner.Id)) // Get the one just created node1get, err := cl.NodeGetWithResponse(ctx, slug1, &openapi.NodeGetParams{}) tests.Ok(t, err, node1get) a.Equal(name1, node1get.JSON200.Name) a.Equal(slug1, node1get.JSON200.Slug) a.Equal("Rich text content.", node1get.JSON200.Description) a.Equal("<body><h1>Nodes</h1><p>Rich text content.</p></body>", *node1get.JSON200.Content) a.Equal(acc.ID.String(), string(node1get.JSON200.Owner.Id)) // Update the one just created name1 = "test-node-1-updated" slug1 = name1 + uuid.NewString() cont1 := "<h1>Nodes</h1><p>Newly changed content.</p>" url1 = "https://cla.ws" prop1 := openapi.Metadata(map[string]any{ "key": "value", }) node1update, err := cl.NodeUpdateWithResponse(ctx, node1.JSON200.Slug, openapi.NodeMutableProps{ Name: &name1, Slug: &slug1, Content: &cont1, Url: nullable.NewNullableWithValue(url1), Meta: &prop1, }, sh.WithSession(ctx)) tests.Ok(t, err, node1update) a.Equal(name1, node1update.JSON200.Name) a.Equal(slug1, node1update.JSON200.Slug) a.Equal("Newly changed content.", node1update.JSON200.Description) a.Equal("<body><h1>Nodes</h1><p>Newly changed content.</p></body>", *node1update.JSON200.Content) r.NotNil(node1update.JSON200.Link) a.Equal(url1, node1update.JSON200.Link.Url) a.Equal(prop1, node1update.JSON200.Meta) t.Run("empty_slug", func(t *testing.T) { name2 := "Testing Node Number Two" + uuid.NewString() slug2 := "" node2, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{ Name: name2, Slug: &slug2, Visibility: &visibility, }, sh.WithSession(ctx)) tests.Ok(t, err, node2) a.Equal(name2, node2.JSON200.Name) a.Contains(node2.JSON200.Slug, "testing-node-number-two") a.Equal("", node2.JSON200.Description) a.Nil(node2.JSON200.Content) a.Nil(node2.JSON200.Link) a.Equal(acc.ID.String(), string(node2.JSON200.Owner.Id)) }) t.Run("remove_link", func(t *testing.T) { name3 := "test-node-with-link" + uuid.NewString() slug3 := name3 url3 := "https://example.com" node3, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{ Name: name3, Slug: &slug3, Url: &url3, Visibility: &visibility, }, sh.WithSession(ctx)) tests.Ok(t, err, node3) r.NotNil(node3.JSON200.Link) a.Equal(url3, node3.JSON200.Link.Url) node3nolink, err := cl.NodeUpdateWithResponse(ctx, node3.JSON200.Slug, openapi.NodeMutableProps{ Url: nullable.NewNullNullable[string](), }, sh.WithSession(ctx)) tests.Ok(t, err, node3nolink) a.Nil(node3nolink.JSON200.Link) node3get, err := cl.NodeGetWithResponse(ctx, node3.JSON200.Slug, &openapi.NodeGetParams{}) tests.Ok(t, err, node3get) a.Nil(node3get.JSON200.Link) }) })) })) } func TestNodesErrors(t *testing.T) { t.Parallel() integration.Test(t, nil, e2e.Setup(), fx.Invoke(func( lc fx.Lifecycle, ctx context.Context, cl *openapi.ClientWithResponses, sh *e2e.SessionHelper, aw *account_writer.Writer, ) { lc.Append(fx.StartHook(func() { r := require.New(t) a := assert.New(t) ctx, _ := e2e.WithAccount(ctx, aw, seed.Account_001_Odin) get404, err := cl.NodeGetWithResponse(ctx, "nonexistent", &openapi.NodeGetParams{}) r.NoError(err) r.NotNil(get404) a.Equal(http.StatusNotFound, get404.StatusCode()) update403, err := cl.NodeUpdateWithResponse(ctx, "nonexistent", openapi.NodeMutableProps{}) r.NoError(err) r.NotNil(update403) a.Equal(http.StatusUnauthorized, update403.StatusCode()) update404, err := cl.NodeUpdateWithResponse(ctx, "nonexistent", openapi.NodeMutableProps{}, sh.WithSession(ctx)) r.NoError(err) r.NotNil(update404) a.Equal(http.StatusNotFound, update404.StatusCode()) t.Run("invalid_slug", func(t *testing.T) { name := "Testing Node Bad Slug" + uuid.NewString() slug := "not@a/good'slug]" create, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{ Name: name, Slug: &slug, }, sh.WithSession(ctx)) tests.Status(t, err, create, http.StatusBadRequest) }) })) })) }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server