Repository: strawberry-graphql/strawberry

Issue:
Codegen drops all but the last field when working with inline fragments.
<!-- Provide a general summary of the bug in the title above. -->

<!--- This template is entirely optional and can be removed, but is here to help both you and us. -->
<!--- Anything on lines wrapped in comments like these will not show up in the final text. -->

## Describe the Bug

I noticed that not all fields are included in the generated types when the query includes an inline fragment.  e.g.

```
query OperationName {
  getPersonOrAnimal {
    ... on Person {
      name
      age
    }
  }
}
```

assuming we add the following to the appropriate conftest for query-generation

```py
    @strawberry.field
    def get_person_or_animal(self) -> Union[Person, Animal]:
        """Randomly get a person or an animal."""
        p_or_a = random.choice([Person, Animal])()
        p_or_a.name = "Howard"
        p_or_a.age = 7
        return p_or_a
```

would only generate an object with an `age` property -- no `name`.  It took me a little while to come up with a MCVE that tripped this up, but the above should deterministically generate objects with missing fields.

## System Information

 - Operating system:
 - Strawberry version (if applicable):

## Additional Context

<!-- Add any other relevant information about the problem here. -->



Discussion:

Resolving patch:
diff --git a/strawberry/codegen/query_codegen.py b/strawberry/codegen/query_codegen.py
--- a/strawberry/codegen/query_codegen.py
+++ b/strawberry/codegen/query_codegen.py
@@ -504,7 +504,9 @@ def _field_from_selection_set(
         selected_field = self.schema.get_field_for_type(
             selection.name.value, parent_type.name
         )
-        assert selected_field
+        assert (
+            selected_field
+        ), f"Couldn't find {parent_type.name}.{selection.name.value}"
 
         selected_field_type, wrapper = self._unwrap_type(selected_field.type)
         name = capitalize_first(to_camel_case(selection.name.value))
@@ -638,14 +640,13 @@ def _collect_types_using_fragments(
 
         for fragment in fragments:
             fragment_class_name = class_name + fragment.type_condition.name.value
-            current_type = GraphQLObjectType(fragment_class_name, [])
+
+            current_type = GraphQLObjectType(fragment_class_name, list(common_fields))
 
             for sub_selection in fragment.selection_set.selections:
                 # TODO: recurse, use existing method ?
                 assert isinstance(sub_selection, FieldNode)
 
-                current_type.fields = list(common_fields)
-
                 parent_type = cast(
                     TypeDefinition,
                     self.schema.get_type_by_name(fragment.type_condition.name.value),


Test patch:
diff --git a/tests/codegen/conftest.py b/tests/codegen/conftest.py
--- a/tests/codegen/conftest.py
+++ b/tests/codegen/conftest.py
@@ -1,7 +1,8 @@
 import datetime
 import decimal
 import enum
-from typing import TYPE_CHECKING, List, NewType, Optional
+import random
+from typing import TYPE_CHECKING, List, NewType, Optional, Union
 from typing_extensions import Annotated
 from uuid import UUID
 
@@ -100,6 +101,14 @@ class Query:
     def with_inputs(self, id: Optional[strawberry.ID], input: ExampleInput) -> bool:
         return True
 
+    @strawberry.field
+    def get_person_or_animal(self) -> Union[Person, Animal]:
+        """Randomly get a person or an animal."""
+        p_or_a = random.choice([Person, Animal])()  # noqa: S311
+        p_or_a.name = "Howard"
+        p_or_a.age = 7
+        return p_or_a
+
 
 @strawberry.type
 class Mutation:
diff --git a/tests/codegen/queries/union_return.graphql b/tests/codegen/queries/union_return.graphql
new file mode 100644
--- /dev/null
+++ b/tests/codegen/queries/union_return.graphql
@@ -0,0 +1,8 @@
+query OperationName {
+  getPersonOrAnimal {
+    ... on Person {
+      name
+      age
+    }
+  }
+}
diff --git a/tests/codegen/queries/union_with_one_type.graphql b/tests/codegen/queries/union_with_one_type.graphql
--- a/tests/codegen/queries/union_with_one_type.graphql
+++ b/tests/codegen/queries/union_with_one_type.graphql
@@ -2,6 +2,7 @@ query OperationName {
   union {
     ... on Animal {
       age
+      name
     }
   }
 }
diff --git a/tests/codegen/snapshots/python/union_return.py b/tests/codegen/snapshots/python/union_return.py
new file mode 100644
--- /dev/null
+++ b/tests/codegen/snapshots/python/union_return.py
@@ -0,0 +1,6 @@
+class OperationNameResultGetPersonOrAnimalPerson:
+    name: str
+    age: int
+
+class OperationNameResult:
+    get_person_or_animal: OperationNameResultGetPersonOrAnimalPerson
diff --git a/tests/codegen/snapshots/python/union_with_one_type.py b/tests/codegen/snapshots/python/union_with_one_type.py
--- a/tests/codegen/snapshots/python/union_with_one_type.py
+++ b/tests/codegen/snapshots/python/union_with_one_type.py
@@ -1,5 +1,6 @@
 class OperationNameResultUnionAnimal:
     age: int
+    name: str
 
 class OperationNameResult:
     union: OperationNameResultUnionAnimal
diff --git a/tests/codegen/snapshots/typescript/union_return.ts b/tests/codegen/snapshots/typescript/union_return.ts
new file mode 100644
--- /dev/null
+++ b/tests/codegen/snapshots/typescript/union_return.ts
@@ -0,0 +1,8 @@
+type OperationNameResultGetPersonOrAnimalPerson = {
+    name: string
+    age: number
+}
+
+type OperationNameResult = {
+    get_person_or_animal: OperationNameResultGetPersonOrAnimalPerson
+}
diff --git a/tests/codegen/snapshots/typescript/union_with_one_type.ts b/tests/codegen/snapshots/typescript/union_with_one_type.ts
--- a/tests/codegen/snapshots/typescript/union_with_one_type.ts
+++ b/tests/codegen/snapshots/typescript/union_with_one_type.ts
@@ -1,5 +1,6 @@
 type OperationNameResultUnionAnimal = {
     age: number
+    name: string
 }
 
 type OperationNameResult = {