diff --git a/server/e2e/gql_project_test.go b/server/e2e/gql_project_test.go index 45f0f23c4f..12e32c18de 100644 --- a/server/e2e/gql_project_test.go +++ b/server/e2e/gql_project_test.go @@ -9,80 +9,46 @@ import ( "github.com/stretchr/testify/assert" ) -func TestCreateProject(t *testing.T) { +func TestCreateAndGetProject(t *testing.T) { e := StartServer(t, &config.Config{ Origins: []string{"https://example.com"}, AuthSrv: config.AuthSrvConfig{ Disabled: true, }, - }, - true, baseSeeder) + }, true, baseSeeder) + + testData(e) - // create project with default coreSupport value (false) + // GetProjects requestBody := GraphQLRequest{ - OperationName: "CreateProject", - Query: "mutation CreateProject($teamId: ID!, $visualizer: Visualizer!, $name: String!, $description: String!, $imageUrl: URL) {\n createProject(\n input: {teamId: $teamId, visualizer: $visualizer, name: $name, description: $description, imageUrl: $imageUrl}\n ) {\n project {\n id\n name\n description\n imageUrl\n coreSupport\n __typename\n }\n __typename\n }\n}", + OperationName: "GetProjects", + Query: "query GetProjects($teamId: ID!, $pagination: Pagination, $keyword: String, $sort: ProjectSort) {\n projects(\n teamId: $teamId\n pagination: $pagination\n keyword: $keyword\n sort: $sort\n ) {\n edges {\n node {\n id\n ...ProjectFragment\n scene {\n id\n __typename\n }\n __typename\n }\n __typename\n }\n nodes {\n id\n ...ProjectFragment\n scene {\n id\n __typename\n }\n __typename\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n __typename\n }\n totalCount\n __typename\n }\n}\n\nfragment ProjectFragment on Project {\n id\n name\n description\n imageUrl\n isArchived\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n publicTitle\n publicDescription\n publicImage\n alias\n enableGa\n trackingId\n publishmentStatus\n updatedAt\n createdAt\n coreSupport\n starred\n isDeleted\n __typename\n}", Variables: map[string]any{ - "name": "test", - "description": "abc", - "imageUrl": "", - "teamId": wID.String(), - "visualizer": "CESIUM", + "teamId": wID.String(), + "pagination": map[string]any{ + "first": 16, + }, + "sort": map[string]string{ + "field": "UPDATEDAT", + "direction": "DESC", + }, }, } + edges := callRequest(e, requestBody). + Value("projects").Object(). + Value("edges").Array() - e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("authorization", "Bearer test"). - // WithHeader("authorization", "Bearer test"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON(). - Object(). - Value("data").Object(). - Value("createProject").Object(). - Value("project").Object(). - // ValueEqual("id", pId.String()). - ValueEqual("name", "test"). - ValueEqual("description", "abc"). - ValueEqual("imageUrl", ""). - ValueEqual("coreSupport", false) + edges.Length().Equal(1) + edges.First().Object().Value("node").Object().Value("name").Equal("test2-1") - // create coreSupport project - requestBody = GraphQLRequest{ - OperationName: "CreateProject", - Query: "mutation CreateProject($teamId: ID!, $visualizer: Visualizer!, $name: String!, $description: String!, $imageUrl: URL, $coreSupport: Boolean) {\n createProject(\n input: {teamId: $teamId, visualizer: $visualizer, name: $name, description: $description, imageUrl: $imageUrl, coreSupport: $coreSupport}\n ) {\n project {\n id\n name\n description\n imageUrl\n coreSupport\n __typename\n }\n __typename\n }\n}", - Variables: map[string]any{ - "name": "test", - "description": "abc", - "imageUrl": "", - "teamId": wID.String(), - "visualizer": "CESIUM", - "coreSupport": true, - }, + // check + for _, edge := range edges.Iter() { + // coreSupport true only + edge.Object().Value("node").Object().Value("coreSupport").Equal(true) + // isDeleted false only + edge.Object().Value("node").Object().Value("isDeleted").Equal(false) } - e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - // WithHeader("authorization", "Bearer test"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON(). - Object(). - Value("data").Object(). - Value("createProject").Object(). - Value("project").Object(). - // ValueEqual("id", pId.String()). - ValueEqual("name", "test"). - ValueEqual("description", "abc"). - ValueEqual("imageUrl", ""). - ValueEqual("coreSupport", true) } func TestSortByName(t *testing.T) { @@ -91,14 +57,12 @@ func TestSortByName(t *testing.T) { AuthSrv: config.AuthSrvConfig{ Disabled: true, }, - }, - true, baseSeeder) + }, true, baseSeeder) createProject(e, "a-project") createProject(e, "b-project") createProject(e, "A-project") createProject(e, "B-project") - seedProjectName := pName requestBody := GraphQLRequest{ OperationName: "GetProjects", @@ -177,25 +141,16 @@ func TestSortByName(t *testing.T) { }, } - edges := e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON(). - Object(). - Value("data").Object(). + edges := callRequest(e, requestBody). Value("projects").Object(). Value("edges").Array() - edges.Length().Equal(5) + edges.Length().Equal(4) edges.Element(0).Object().Value("node").Object().Value("name").Equal("a-project") edges.Element(1).Object().Value("node").Object().Value("name").Equal("A-project") edges.Element(2).Object().Value("node").Object().Value("name").Equal("b-project") edges.Element(3).Object().Value("node").Object().Value("name").Equal("B-project") - edges.Element(4).Object().Value("node").Object().Value("name").Equal(seedProjectName) + } func TestFindStarredByWorkspace(t *testing.T) { @@ -237,17 +192,8 @@ func TestFindStarredByWorkspace(t *testing.T) { }, } - response := e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON(). - Object() - - starredProjects := response.Value("data").Object().Value("starredProjects").Object() + starredProjects := callRequest(e, requestBody). + Value("starredProjects").Object() totalCount := starredProjects.Value("totalCount").Raw() assert.Equal(t, float64(2), totalCount, "Expected 2 starred projects") @@ -302,16 +248,7 @@ func starProject(e *httpexpect.Expect, projectID string) { }, } - response := e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(updateProjectMutation). - Expect(). - Status(http.StatusOK). - JSON(). - Object(). - Value("data").Object(). + response := callRequest(e, updateProjectMutation). Value("updateProject").Object(). Value("project").Object() @@ -332,7 +269,7 @@ func TestSortByUpdatedAt(t *testing.T) { project2ID := createProject(e, "project2-test") createProject(e, "project3-test") - requestBody := GraphQLRequest{ + updateProjectMutation := GraphQLRequest{ OperationName: "UpdateProject", Query: `mutation UpdateProject($input: UpdateProjectInput!) { updateProject(input: $input) { @@ -355,16 +292,11 @@ func TestSortByUpdatedAt(t *testing.T) { } // Update 'project2' - e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON() + callRequest(e, updateProjectMutation). + Value("updateProject").Object(). + Value("project").Object() - requestBody = GraphQLRequest{ + requestBody := GraphQLRequest{ OperationName: "GetProjects", Query: ` query GetProjects($teamId: ID!, $pagination: Pagination, $keyword: String, $sort: ProjectSort) { @@ -440,16 +372,7 @@ func TestSortByUpdatedAt(t *testing.T) { }, } - edges := e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON(). - Object(). - Value("data").Object(). + edges := callRequest(e, requestBody). Value("projects").Object(). Value("edges").Array() @@ -457,8 +380,6 @@ func TestSortByUpdatedAt(t *testing.T) { edges.Element(0).Object().Value("node").Object().Value("name").Equal("project2-test") // 'project2' is first } -// go test -v -run TestDeleteProjects ./e2e/... - func TestDeleteProjects(t *testing.T) { e := StartServer(t, &config.Config{ @@ -468,12 +389,7 @@ func TestDeleteProjects(t *testing.T) { }, }, true, baseSeeder) - createProject(e, "project1-test") - project2ID := createProject(e, "project2-test") - createProject(e, "project3-test") - - // Deleted 'project2' - deleteProject(e, project2ID) + testData(e) // check requestBody := GraphQLRequest{ @@ -485,6 +401,7 @@ func TestDeleteProjects(t *testing.T) { id name isDeleted + coreSupport } totalCount } @@ -493,19 +410,20 @@ func TestDeleteProjects(t *testing.T) { "teamId": wID, }, } - deletedProjects := e.POST("/api/graphql"). - WithHeader("Origin", "https://example.com"). - WithHeader("X-Reearth-Debug-User", uID.String()). - WithHeader("Content-Type", "application/json"). - WithJSON(requestBody). - Expect(). - Status(http.StatusOK). - JSON(). - Object().Value("data").Object().Value("deletedProjects").Object() + nodes := callRequest(e, requestBody). + Value("deletedProjects").Object(). + Value("nodes").Array() - deletedProjects.Value("totalCount").Equal(1) - deletedProjects.Value("nodes").Array().Length().Equal(1) - deletedProjects.Value("nodes").Array().First().Object().Value("name").Equal("project2-test") + nodes.Length().Equal(1) + nodes.First().Object().Value("name").Equal("test2-2") + + // check + for _, node := range nodes.Iter() { + // coreSupport true only + node.Object().Value("coreSupport").Equal(true) + // isDeleted true only + node.Object().Value("isDeleted").Equal(true) + } } func deleteProject(e *httpexpect.Expect, projectID string) { @@ -532,19 +450,104 @@ func deleteProject(e *httpexpect.Expect, projectID string) { }, } - response := e.POST("/api/graphql"). + response := callRequest(e, updateProjectMutation). + Value("updateProject").Object(). + Value("project").Object() + + response.ValueEqual("id", projectID). + ValueEqual("isDeleted", true) +} + +func createGraphQLRequest(name string, coreSupport bool) GraphQLRequest { + return GraphQLRequest{ + OperationName: "CreateProject", + Query: "mutation CreateProject($teamId: ID!, $visualizer: Visualizer!, $name: String!, $description: String!, $imageUrl: URL, $coreSupport: Boolean) {\n createProject(\n input: {teamId: $teamId, visualizer: $visualizer, name: $name, description: $description, imageUrl: $imageUrl, coreSupport: $coreSupport}\n ) {\n project {\n id\n name\n description\n imageUrl\n coreSupport\n __typename\n }\n __typename\n }\n}", + Variables: map[string]any{ + "name": name, + "description": "abc", + "imageUrl": "", + "teamId": wID.String(), + "visualizer": "CESIUM", + "coreSupport": coreSupport, + }, + } +} + +func callRequest(e *httpexpect.Expect, requestBody GraphQLRequest) *httpexpect.Object { + return e.POST("/api/graphql"). WithHeader("Origin", "https://example.com"). + WithHeader("authorization", "Bearer test"). WithHeader("X-Reearth-Debug-User", uID.String()). WithHeader("Content-Type", "application/json"). - WithJSON(updateProjectMutation). + WithJSON(requestBody). Expect(). Status(http.StatusOK). JSON(). Object(). - Value("data").Object(). - Value("updateProject").Object(). - Value("project").Object() + Value("data").Object() +} - response.ValueEqual("id", projectID). - ValueEqual("isDeleted", true) +func testData(e *httpexpect.Expect) { + + // create coreSupport default(=false) project + requestBody := GraphQLRequest{ + OperationName: "CreateProject", + Query: "mutation CreateProject($teamId: ID!, $visualizer: Visualizer!, $name: String!, $description: String!, $imageUrl: URL) {\n createProject(\n input: {teamId: $teamId, visualizer: $visualizer, name: $name, description: $description, imageUrl: $imageUrl}\n ) {\n project {\n id\n name\n description\n imageUrl\n coreSupport\n __typename\n }\n __typename\n }\n}", + Variables: map[string]any{ + "name": "test1-1", + "description": "abc", + "imageUrl": "", + "teamId": wID.String(), + "visualizer": "CESIUM", + }, + } + callRequest(e, requestBody).Value("createProject").Object().Value("project").Object(). + ValueEqual("name", "test1-1"). + ValueEqual("coreSupport", false) + + // create coreSupport default(=false) `delete` project + requestBody = GraphQLRequest{ + OperationName: "CreateProject", + Query: "mutation CreateProject($teamId: ID!, $visualizer: Visualizer!, $name: String!, $description: String!, $imageUrl: URL) {\n createProject(\n input: {teamId: $teamId, visualizer: $visualizer, name: $name, description: $description, imageUrl: $imageUrl}\n ) {\n project {\n id\n name\n description\n imageUrl\n coreSupport\n __typename\n }\n __typename\n }\n}", + Variables: map[string]any{ + "name": "test1-2", + "description": "abc", + "imageUrl": "", + "teamId": wID.String(), + "visualizer": "CESIUM", + }, + } + id := callRequest(e, requestBody).Value("createProject").Object().Value("project").Object(). + ValueEqual("name", "test1-2"). + ValueEqual("coreSupport", false). + Value("id").Raw().(string) + deleteProject(e, id) // delete + + // create coreSupport:true project + requestBody = createGraphQLRequest("test2-1", true) + callRequest(e, requestBody).Value("createProject").Object().Value("project").Object(). + ValueEqual("name", "test2-1"). + ValueEqual("coreSupport", true) + + // create coreSupport:true `delete` project + requestBody = createGraphQLRequest("test2-2", true) + id = callRequest(e, requestBody).Value("createProject").Object().Value("project").Object(). + ValueEqual("name", "test2-2"). + ValueEqual("coreSupport", true). + Value("id").Raw().(string) + deleteProject(e, id) // delete + + // create coreSupport:false project + requestBody = createGraphQLRequest("test3-1", false) + callRequest(e, requestBody).Value("createProject").Object().Value("project").Object(). + ValueEqual("name", "test3-1"). + ValueEqual("coreSupport", false) + + // create coreSupport:false `delete` project + requestBody = createGraphQLRequest("test3-2", false) + id = callRequest(e, requestBody).Value("createProject").Object().Value("project").Object(). + ValueEqual("name", "test3-2"). + ValueEqual("coreSupport", false). + Value("id").Raw().(string) + deleteProject(e, id) // delete } diff --git a/server/internal/infrastructure/memory/project.go b/server/internal/infrastructure/memory/project.go index 1c98a66840..9f3459e219 100644 --- a/server/internal/infrastructure/memory/project.go +++ b/server/internal/infrastructure/memory/project.go @@ -45,7 +45,7 @@ func (r *Project) FindByWorkspace(ctx context.Context, id accountdomain.Workspac result := []*project.Project{} for _, d := range r.data { - if d.Workspace() == id && !d.IsDeleted() && (filter.Keyword == nil || strings.Contains(d.Name(), *filter.Keyword)) { + if d.Workspace() == id && !d.IsDeleted() && d.CoreSupport() && (filter.Keyword == nil || strings.Contains(d.Name(), *filter.Keyword)) { result = append(result, d) } } @@ -93,7 +93,7 @@ func (r *Project) FindStarredByWorkspace(ctx context.Context, id accountdomain.W var result []*project.Project for _, p := range r.data { - if p.Workspace() == id && p.Starred() { + if p.Workspace() == id && p.Starred() && p.CoreSupport() { result = append(result, p) } } @@ -115,7 +115,7 @@ func (r *Project) FindDeletedByWorkspace(ctx context.Context, id accountdomain.W var result []*project.Project for _, p := range r.data { - if p.Workspace() == id && p.IsDeleted() { + if p.Workspace() == id && p.IsDeleted() && p.CoreSupport() { result = append(result, p) } } diff --git a/server/internal/infrastructure/mongo/project.go b/server/internal/infrastructure/mongo/project.go index f68aa9b5c4..6d7291dbef 100644 --- a/server/internal/infrastructure/mongo/project.go +++ b/server/internal/infrastructure/mongo/project.go @@ -85,9 +85,19 @@ func (r *Project) FindByWorkspace(ctx context.Context, id accountdomain.Workspac filter := bson.M{ "team": id.String(), - "$or": []bson.M{ - {"deleted": false}, - {"deleted": bson.M{"$exists": false}}, + "$and": []bson.M{ + { + "$or": []bson.M{ + {"deleted": false}, + {"deleted": bson.M{"$exists": false}}, + }, + }, + { + "$or": []bson.M{ + {"coresupport": true}, + {"coresupport": bson.M{"$exists": false}}, + }, + }, }, } @@ -114,9 +124,19 @@ func (r *Project) FindStarredByWorkspace(ctx context.Context, id accountdomain.W filter := bson.M{ "team": id.String(), "starred": true, - "$or": []bson.M{ - {"deleted": false}, - {"deleted": bson.M{"$exists": false}}, + "$and": []bson.M{ + { + "$or": []bson.M{ + {"deleted": false}, + {"deleted": bson.M{"$exists": false}}, + }, + }, + { + "$or": []bson.M{ + {"coresupport": true}, + {"coresupport": bson.M{"$exists": false}}, + }, + }, }, } @@ -129,8 +149,9 @@ func (r *Project) FindDeletedByWorkspace(ctx context.Context, id accountdomain.W } filter := bson.M{ - "team": id.String(), - "deleted": true, + "team": id.String(), + "deleted": true, + "coresupport": true, } return r.find(ctx, filter)