Repository: kiwicom/mobile
Pull request #1324 (2018-11-13 12:07:02)

Stay22: save paymentLink to context, refactor bedding info

tbergq: @RobinCsl 🚀 

Patch:
diff --git a/app/hotels/src/HotelsContext.js b/app/hotels/src/HotelsContext.js
index 8f062511..ff26c1c8 100644
--- a/app/hotels/src/HotelsContext.js
+++ b/app/hotels/src/HotelsContext.js
@@ -17,6 +17,7 @@ const defaultState = {
   cityName: null,
   latitude: null,
   longitude: null,
+  paymentLink: null,
   currentSearchStats: {
     priceMax: 10000,
     priceMin: 0,
@@ -26,6 +27,7 @@ const defaultState = {
   },
   getGuestCount: () => 0,
   setHotelId: () => {},
+  setPaymentLink: () => {},
 };
 
 const { Consumer, Provider: ContextProvider } = React.createContext<State>({
@@ -69,6 +71,8 @@ type State = {|
   currentSearchStats: CurrentSearchStats,
   +latitude: number | null,
   +longitude: number | null,
+  paymentLink: ?string,
+  +setPaymentLink: (?string) => void,
   +getGuestCount: () => number,
   +setHotelId: (hotelId: string) => void,
   +actions: {|
@@ -108,12 +112,14 @@ class Provider extends React.Component<Props, State> {
       cityName: props.cityName || null,
       latitude: props.latitude || null,
       longitude: props.longitude || null,
+      paymentLink: null,
       currentSearchStats: {
         priceMax: 10000,
         priceMin: 0,
       },
       getGuestCount: this.getGuestCount,
       setHotelId: this.setHotelId,
+      setPaymentLink: this.setPaymentLink,
       actions: {
         setCurrentSearchStats: this.setCurrentSearchStats,
       },
@@ -139,6 +145,8 @@ class Provider extends React.Component<Props, State> {
     }, 0);
   };
 
+  setPaymentLink = (paymentLink: ?string) => this.setState({ paymentLink });
+
   render = () => (
     <ContextProvider value={this.state}>{this.props.children}</ContextProvider>
   );
diff --git a/app/hotels/src/singleHotel/HotelDetailScreen.js b/app/hotels/src/singleHotel/HotelDetailScreen.js
index a1ec8149..ed449f89 100644
--- a/app/hotels/src/singleHotel/HotelDetailScreen.js
+++ b/app/hotels/src/singleHotel/HotelDetailScreen.js
@@ -28,7 +28,11 @@ import BrandLabel from './brandLabel/BrandLabel';
 import type { RoomsConfiguration } from '../singleHotel/AvailableHotelSearchInput';
 import type { HotelDetailScreen_availableHotel } from './__generated__/HotelDetailScreen_availableHotel.graphql';
 import countBookingPrice from './bookNow/countBookingPrice';
-import { withHotelsContext, type HotelsContextState } from '../HotelsContext';
+import {
+  withHotelsContext,
+  type HotelsContextState,
+  type ApiProvider,
+} from '../HotelsContext';
 
 type PropsWithContext = {|
   ...Props,
@@ -68,12 +72,21 @@ export class HotelDetailScreen extends React.Component<
     };
   }
 
-  componentDidMount = () => {
-    Logger.ancillaryDisplayed(
-      Logger.Type.ANCILLARY_STEP_DETAILS,
-      Logger.Provider.ANCILLARY_PROVIDER_BOOKINGCOM,
-    );
-  };
+  componentDidMount() {
+    const {
+      ANCILLARY_PROVIDER_BOOKINGCOM,
+      ANCILLARY_PROVIDER_STAY22,
+    } = Logger.Provider;
+
+    const provider =
+      this.props.apiProvider === 'booking'
+        ? ANCILLARY_PROVIDER_BOOKINGCOM
+        : ANCILLARY_PROVIDER_STAY22;
+
+    Logger.ancillaryDisplayed(Logger.Type.ANCILLARY_STEP_DETAILS, provider);
+
+    this.props.setPaymentLink(this.props.paymentLink);
+  }
 
   shouldComponentUpdate = (nextProps: PropsWithContext, nextState: State) => {
     const isPropsEqual = isEqual(nextProps, this.props);
@@ -221,6 +234,9 @@ type Props = {|
   +roomsConfiguration: RoomsConfiguration,
   +goBack: () => void,
   +getGuestCount: () => number,
+  +paymentLink?: ?string,
+  +setPaymentLink: (?string) => void,
+  +apiProvider: ApiProvider,
 |};
 
 class HotelDetailScreenWithContext extends React.Component<Props> {
@@ -233,7 +249,15 @@ class HotelDetailScreenWithContext extends React.Component<Props> {
   }
 }
 
-const select = ({ getGuestCount }: HotelsContextState) => ({ getGuestCount });
+const select = ({
+  getGuestCount,
+  setPaymentLink,
+  apiProvider,
+}: HotelsContextState) => ({
+  getGuestCount,
+  setPaymentLink,
+  apiProvider,
+});
 
 export default createFragmentContainer(
   withHotelsContext(select)(HotelDetailScreenWithContext),
diff --git a/app/hotels/src/singleHotel/Stay22SingleHotel.js b/app/hotels/src/singleHotel/Stay22SingleHotel.js
index f5c01ee9..7c280b33 100644
--- a/app/hotels/src/singleHotel/Stay22SingleHotel.js
+++ b/app/hotels/src/singleHotel/Stay22SingleHotel.js
@@ -24,6 +24,7 @@ export default class Stay22SingleHotel extends React.Component<Props> {
       availableHotel={stay22HotelDetail}
       roomsConfiguration={this.props.roomsConfiguration}
       goBack={this.props.goBack}
+      paymentLink={stay22HotelDetail?.paymentLink}
     />
   );
 
@@ -50,6 +51,7 @@ export default class Stay22SingleHotel extends React.Component<Props> {
               checkout: $checkout
             ) {
               ...HotelDetailScreen_availableHotel
+              paymentLink
             }
           }
         `}
diff --git a/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js b/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js
index c8426956..1aa6578f 100644
--- a/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js
+++ b/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 0dd032a334f5b0752f9f632eb680eaf6
+ * @relayHash 4720e8f50008833643781e2f35e7594f
  */
 
 /* eslint-disable */
@@ -20,7 +20,8 @@ export type Stay22SingleHotelQueryVariables = {|
 |};
 export type Stay22SingleHotelQueryResponse = {|
   +stay22HotelDetail: ?{|
-    +$fragmentRefs: HotelDetailScreen_availableHotel$ref
+    +paymentLink: ?string,
+    +$fragmentRefs: HotelDetailScreen_availableHotel$ref,
   |}
 |};
 export type Stay22SingleHotelQuery = {|
@@ -40,6 +41,7 @@ query Stay22SingleHotelQuery(
 ) {
   stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {
     ...HotelDetailScreen_availableHotel
+    paymentLink
     id
   }
 }
@@ -245,47 +247,54 @@ v1 = [
 v2 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "__typename",
+  "name": "paymentLink",
   "args": null,
   "storageKey": null
 },
 v3 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "name",
+  "name": "__typename",
   "args": null,
   "storageKey": null
 },
 v4 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "highResUrl",
+  "name": "name",
   "args": null,
   "storageKey": null
 },
 v5 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "id",
+  "name": "highResUrl",
   "args": null,
   "storageKey": null
 },
 v6 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "lowResUrl",
+  "name": "id",
   "args": null,
   "storageKey": null
 },
 v7 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "lowResUrl",
+  "args": null,
+  "storageKey": null
+},
+v8 = {
   "kind": "ScalarField",
   "alias": null,
   "name": "amount",
   "args": null,
   "storageKey": null
 },
-v8 = [
-  v7,
+v9 = [
+  v8,
   {
     "kind": "ScalarField",
     "alias": null,
@@ -299,7 +308,7 @@ return {
   "operationKind": "query",
   "name": "Stay22SingleHotelQuery",
   "id": null,
-  "text": "query Stay22SingleHotelQuery(\n  $id: ID!\n  $guests: Int!\n  $currency: Currency\n  $checkin: Date!\n  $checkout: Date!\n) {\n  stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {\n    ...HotelDetailScreen_availableHotel\n    id\n  }\n}\n\nfragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {\n  hotel {\n    __typename\n    ...Header_hotel\n    ...BookNow_hotel\n    ...HotelInformation_hotel\n    id\n  }\n  availableRooms {\n    __typename\n    ...RoomList\n    id\n    incrementalPrice {\n      amount\n      currency\n    }\n  }\n}\n\nfragment Header_hotel on HotelInterface {\n  name\n  mainPhoto {\n    highResUrl\n    id\n  }\n  rating {\n    stars\n    categoryName\n  }\n  photos {\n    edges {\n      node {\n        id\n        lowResUrl\n        highResUrl\n      }\n    }\n  }\n}\n\nfragment BookNow_hotel on HotelInterface {\n  id\n}\n\nfragment HotelInformation_hotel on HotelInterface {\n  ...Location_hotel\n  ...Description_hotel\n  ...HotelReview\n}\n\nfragment RoomList on HotelRoomAvailabilityInterface {\n  id\n  ...RoomRow_availableRoom\n}\n\nfragment RoomRow_availableRoom on HotelRoomAvailabilityInterface {\n  id\n  ...RoomBadges_availableRoom\n  minimalPrice {\n    amount\n    currency\n  }\n  incrementalPrice {\n    amount\n    currency\n  }\n  room {\n    __typename\n    description {\n      title\n    }\n    ...RoomRowTitle_room\n    roomPhotos {\n      highResUrl\n      lowResUrl\n      id\n    }\n    maxPersons\n    ...BeddingInfo_room\n    id\n  }\n}\n\nfragment RoomBadges_availableRoom on HotelRoomAvailabilityInterface {\n  isBreakfastIncluded\n  isRefundable\n}\n\nfragment RoomRowTitle_room on HotelRoomInterface {\n  description {\n    title\n  }\n}\n\nfragment BeddingInfo_room on HotelRoomInterface {\n  maxPersons\n  bedding {\n    type\n    amount\n  }\n}\n\nfragment Location_hotel on HotelInterface {\n  address {\n    street\n    city\n  }\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment Description_hotel on HotelInterface {\n  summary\n  ...Amenities\n}\n\nfragment HotelReview on HotelInterface {\n  review {\n    score\n    count\n  }\n}\n\nfragment Amenities on HotelInterface {\n  amenities {\n    id\n    name\n  }\n}\n",
+  "text": "query Stay22SingleHotelQuery(\n  $id: ID!\n  $guests: Int!\n  $currency: Currency\n  $checkin: Date!\n  $checkout: Date!\n) {\n  stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {\n    ...HotelDetailScreen_availableHotel\n    paymentLink\n    id\n  }\n}\n\nfragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {\n  hotel {\n    __typename\n    ...Header_hotel\n    ...BookNow_hotel\n    ...HotelInformation_hotel\n    id\n  }\n  availableRooms {\n    __typename\n    ...RoomList\n    id\n    incrementalPrice {\n      amount\n      currency\n    }\n  }\n}\n\nfragment Header_hotel on HotelInterface {\n  name\n  mainPhoto {\n    highResUrl\n    id\n  }\n  rating {\n    stars\n    categoryName\n  }\n  photos {\n    edges {\n      node {\n        id\n        lowResUrl\n        highResUrl\n      }\n    }\n  }\n}\n\nfragment BookNow_hotel on HotelInterface {\n  id\n}\n\nfragment HotelInformation_hotel on HotelInterface {\n  ...Location_hotel\n  ...Description_hotel\n  ...HotelReview\n}\n\nfragment RoomList on HotelRoomAvailabilityInterface {\n  id\n  ...RoomRow_availableRoom\n}\n\nfragment RoomRow_availableRoom on HotelRoomAvailabilityInterface {\n  id\n  ...RoomBadges_availableRoom\n  minimalPrice {\n    amount\n    currency\n  }\n  incrementalPrice {\n    amount\n    currency\n  }\n  room {\n    __typename\n    description {\n      title\n    }\n    ...RoomRowTitle_room\n    roomPhotos {\n      highResUrl\n      lowResUrl\n      id\n    }\n    maxPersons\n    ...BeddingInfo_room\n    id\n  }\n}\n\nfragment RoomBadges_availableRoom on HotelRoomAvailabilityInterface {\n  isBreakfastIncluded\n  isRefundable\n}\n\nfragment RoomRowTitle_room on HotelRoomInterface {\n  description {\n    title\n  }\n}\n\nfragment BeddingInfo_room on HotelRoomInterface {\n  maxPersons\n  bedding {\n    type\n    amount\n  }\n}\n\nfragment Location_hotel on HotelInterface {\n  address {\n    street\n    city\n  }\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment Description_hotel on HotelInterface {\n  summary\n  ...Amenities\n}\n\nfragment HotelReview on HotelInterface {\n  review {\n    score\n    count\n  }\n}\n\nfragment Amenities on HotelInterface {\n  amenities {\n    id\n    name\n  }\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -321,7 +330,8 @@ return {
             "kind": "FragmentSpread",
             "name": "HotelDetailScreen_availableHotel",
             "args": null
-          }
+          },
+          v2
         ]
       }
     ]
@@ -349,8 +359,8 @@ return {
             "concreteType": null,
             "plural": false,
             "selections": [
-              v2,
               v3,
+              v4,
               {
                 "kind": "LinkedField",
                 "alias": null,
@@ -360,8 +370,8 @@ return {
                 "concreteType": "HotelPhoto",
                 "plural": false,
                 "selections": [
-                  v4,
-                  v5
+                  v5,
+                  v6
                 ]
               },
               {
@@ -416,16 +426,16 @@ return {
                         "concreteType": "HotelPhoto",
                         "plural": false,
                         "selections": [
-                          v5,
                           v6,
-                          v4
+                          v7,
+                          v5
                         ]
                       }
                     ]
                   }
                 ]
               },
-              v5,
+              v6,
               {
                 "kind": "LinkedField",
                 "alias": null,
@@ -492,8 +502,8 @@ return {
                 "concreteType": "HotelAmenity",
                 "plural": true,
                 "selections": [
-                  v5,
-                  v3
+                  v6,
+                  v4
                 ]
               },
               {
@@ -532,8 +542,8 @@ return {
             "concreteType": null,
             "plural": true,
             "selections": [
-              v2,
-              v5,
+              v3,
+              v6,
               {
                 "kind": "ScalarField",
                 "alias": null,
@@ -556,7 +566,7 @@ return {
                 "args": null,
                 "concreteType": "Price",
                 "plural": false,
-                "selections": v8
+                "selections": v9
               },
               {
                 "kind": "LinkedField",
@@ -566,7 +576,7 @@ return {
                 "args": null,
                 "concreteType": "Price",
                 "plural": true,
-                "selections": v8
+                "selections": v9
               },
               {
                 "kind": "LinkedField",
@@ -577,7 +587,7 @@ return {
                 "concreteType": null,
                 "plural": false,
                 "selections": [
-                  v2,
+                  v3,
                   {
                     "kind": "LinkedField",
                     "alias": null,
@@ -605,9 +615,9 @@ return {
                     "concreteType": "HotelPhoto",
                     "plural": true,
                     "selections": [
-                      v4,
-                      v6,
-                      v5
+                      v5,
+                      v7,
+                      v6
                     ]
                   },
                   {
@@ -633,15 +643,16 @@ return {
                         "args": null,
                         "storageKey": null
                       },
-                      v7
+                      v8
                     ]
                   },
-                  v5
+                  v6
                 ]
               }
             ]
           },
-          v5
+          v2,
+          v6
         ]
       }
     ]
@@ -649,5 +660,5 @@ return {
 };
 })();
 // prettier-ignore
-(node/*: any*/).hash = '1636debee894167a789c2b90ad303f18';
+(node/*: any*/).hash = 'bbfb01d8bcca6bb433ffb9cfa9ff927b';
 module.exports = node;
diff --git a/app/hotels/src/singleHotel/roomList/BeddingInfo.js b/app/hotels/src/singleHotel/roomList/BeddingInfo.js
index 0709c0b4..d238fe22 100644
--- a/app/hotels/src/singleHotel/roomList/BeddingInfo.js
+++ b/app/hotels/src/singleHotel/roomList/BeddingInfo.js
@@ -8,7 +8,6 @@ import { Translation } from '@kiwicom/mobile-localization';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import type { BeddingInfo_room } from './__generated__/BeddingInfo_room.graphql';
-import formatBeddingInfo from './formatBeddingInfo';
 
 type ContainerProps = {|
   room: any,
@@ -20,17 +19,28 @@ type Props = {
 };
 
 export class BeddingInfo extends React.Component<Props> {
+  formatBeddingInfo = (): string => {
+    const { room } = this.props;
+    const beddingOptions = room?.bedding ?? [];
+    return beddingOptions
+      .map(beddingOption => {
+        const type = beddingOption?.type;
+        const amount = beddingOption?.amount;
+        return [amount, type].filter(value => value != null).join(' ');
+      })
+      .join(' or '); // TODO: Translate
+  };
+
   render = () => {
     const { room } = this.props;
-    const info = formatBeddingInfo(room);
-    const maxPersons = this.props.room?.maxPersons;
+    const maxPersons = room?.maxPersons;
 
     return (
       <View>
         <View style={styles.row}>
           <TextIcon code="&#xe085;" style={styles.icon} />
           <Text style={styles.text}>
-            <Translation passThrough={` ${info}`} />
+            <Translation passThrough={` ${this.formatBeddingInfo()}`} />
           </Text>
         </View>
         <View style={styles.row}>
diff --git a/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js b/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js
deleted file mode 100644
index 9d927edc..00000000
--- a/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// @flow
-
-import type { BeddingInfo_room } from './__generated__/BeddingInfo_room.graphql';
-
-export default (room: ?BeddingInfo_room): string => {
-  const beddingOptions = room?.bedding ?? [];
-  return beddingOptions
-    .map(beddingOption => {
-      const type = beddingOption?.type;
-      const amount = beddingOption?.amount;
-      return [amount, type].filter(value => value != null).join(' ');
-    })
-    .join(' or '); // TODO: Translate
-};
diff --git a/schema.graphql b/schema.graphql
index 57513711..95698578 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -725,6 +725,17 @@ type Carrier {
   isLowCost: Boolean
 }
 
+type CheckEmailResponse {
+  result: CheckEmailResult
+}
+
+type CheckEmailResult {
+  hasKiwiAccount: Boolean
+  hasFacebook: Boolean
+  hasGoogle: Boolean
+  hasBooking: Boolean
+}
+
 type CheckinClosingTimelineEvent implements TimelineEvent {
   """Time of appearance in the timeline."""
   timestamp: DateTime
@@ -755,6 +766,28 @@ enum CoveredBy {
   CARRIER
 }
 
+enum CreateAccountError {
+  WEAK_PASSWORD
+  ACCOUNT_EXISTS
+  INVALID_EMAIL
+}
+
+input CreateAccountInput {
+  email: String!
+  password: String!
+
+  """Username for login. Email is used if not provided."""
+  login: String
+  firstName: String = ""
+  lastName: String = ""
+}
+
+type CreateAccountResponse {
+  success: Boolean
+  error: CreateAccountError
+  identity: Identity
+}
+
 enum Currency {
   AED
   AFN
@@ -2224,7 +2257,12 @@ type RoomsConfigurationOutput {
 """Root Mutation."""
 type RootMutation {
   login(email: String!, password: String!): User
+  createAccount(credentials: CreateAccountInput!, brand: String = "kiwicom"): CreateAccountResponse
   resetPassword(email: String!): ResetPasswordResponse
+  checkEmail(email: String!): CheckEmailResponse
+
+  """Sends time limited link on given e-mail to log in."""
+  sendMagicLink(email: String!, brand: String = "kiwicom"): SendMagicLinkResponse
   updatePassenger(
     """The global booking id"""
     id: ID!
@@ -2236,6 +2274,7 @@ type RootMutation {
     id: ID!
     simpleToken: String!
     passengers: [PassengerInsuranceInput!]!
+    brand: String = "kiwicom"
   ): Booking
   voteFAQArticle(
     """ID of FAQ article to receive vote."""
@@ -2379,6 +2418,7 @@ type RootQuery {
     """Only Booking id can be used as ID."""
     id: ID!
     authToken: String
+    brand: String = "kiwicom"
   ): BookingTimeline
 
   """Currencies used on Kiwi.com frontend"""
@@ -2406,6 +2446,7 @@ type RootQuery {
     argument to fetch all bookings in ascendering order.
     """
     order: CustomerBookingsOrderEnum
+    brand: String = "kiwicom"
     after: String
     first: Int
     before: String
@@ -2477,7 +2518,7 @@ type RootQuery {
   the smallest difference between current time and arrival time of one of its
   Legs. If no future booking is found, then the nearest past booking is returned.
   """
-  nearestBooking: BookingInterface
+  nearestBooking(brand: String = "kiwicom"): BookingInterface
 
   """Fetches an object given its ID"""
   node(
@@ -2494,6 +2535,7 @@ type RootQuery {
 
     """Simple auth token that lets you fetch a unique booking."""
     authToken: String
+    brand: String = "kiwicom"
   ): BookingInterface
 
   """Single hotel by ID."""
@@ -2515,6 +2557,10 @@ type RouteStop {
   gate: String
 }
 
+type SendMagicLinkResponse {
+  success: Boolean
+}
+
 type Services {
   """Travel insurance - returns "null" if not available."""
   insurance: InsuranceService
@@ -2556,6 +2602,7 @@ type Stay22HotelDetail implements HotelAvailabilityInterface {
   price: Price
   hotel: Stay22Hotel
   availableRooms: [Stay22HotelRoomAvailability]
+  paymentLink: String
 }
 
 type Stay22HotelRoom implements HotelRoomInterface {


Test patch:
diff --git a/app/hotels/src/singleHotel/roomList/__tests__/formatBeddingInfo.test.js b/app/hotels/src/singleHotel/roomList/__tests__/formatBeddingInfo.test.js
index c5518d07..d42ffe89 100644
--- a/app/hotels/src/singleHotel/roomList/__tests__/formatBeddingInfo.test.js
+++ b/app/hotels/src/singleHotel/roomList/__tests__/formatBeddingInfo.test.js
@@ -1,11 +1,11 @@
 // @flow
 
-import formatBeddingInfo from '../formatBeddingInfo';
+import { BeddingInfo } from '../BeddingInfo';
 
 it('formats bedding information', () => {
-  expect(
-    // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
-    formatBeddingInfo({
+  // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
+  const Component = new BeddingInfo({
+    room: {
       type: 'Single Room',
       maxPersons: 1,
       bedding: [
@@ -14,14 +14,15 @@ it('formats bedding information', () => {
           amount: 1,
         },
       ],
-    }),
-  ).toMatchSnapshot();
+    },
+  });
+  expect(Component.formatBeddingInfo()).toMatchSnapshot();
 });
 
 it('pluralizes persons', () => {
-  expect(
-    // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
-    formatBeddingInfo({
+  // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
+  const Component = new BeddingInfo({
+    room: {
       type: 'Double Room',
       maxPersons: 2,
       bedding: [
@@ -30,14 +31,15 @@ it('pluralizes persons', () => {
           amount: 2,
         },
       ],
-    }),
-  ).toMatchSnapshot();
+    },
+  });
+  expect(Component.formatBeddingInfo()).toMatchSnapshot();
 });
 
 it('provides all bedding options', () => {
-  expect(
-    // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
-    formatBeddingInfo({
+  // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
+  const Component = new BeddingInfo({
+    room: {
       type: 'Double or Twin Room',
       maxPersons: 2,
       bedding: [
@@ -50,18 +52,21 @@ it('provides all bedding options', () => {
           amount: 1,
         },
       ],
-    }),
-  ).toMatchSnapshot();
+    },
+  });
+  expect(Component.formatBeddingInfo()).toMatchSnapshot();
 });
 
 it("doesn't crash on empty input", () => {
-  expect(formatBeddingInfo(null)).toEqual('');
+  expect(new BeddingInfo({ room: null }).formatBeddingInfo()).toEqual('');
   expect(
     // $FlowRelayIssue: https://github.com/facebook/relay/issues/2394
-    formatBeddingInfo({
-      type: 'Some Room',
-      maxPersons: 2,
-      bedding: null,
-    }),
+    new BeddingInfo({
+      room: {
+        type: 'Some Room',
+        maxPersons: 2,
+        bedding: null,
+      },
+    }).formatBeddingInfo(),
   ).toMatchSnapshot();
 });