summaryrefslogtreecommitdiff
path: root/Homework/cs5260/consumer/t/DynamoWidgetDAO.spec.ts
blob: 01ea1857cf1c62a47df54c3d40daa31041b44614 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { Widget } from "@/shared/schema";
import { expect, test, mock } from "bun:test";
import {
  DeleteItemCommand,
  DynamoDBClient,
  GetItemCommand,
  PutItemCommand,
} from "@aws-sdk/client-dynamodb";
import { DynamoWidgetDAO } from "@/consumer/dao";
import { VoidLogger } from "@/shared/t";

const testTable = "widgets-t";
const testWidget = Widget.parse({
  id: "testWidgetId",
  owner: "simponic",
  label: "A Widget",
  description: "Nothing to see here!",
  otherAttributes: [{ name: "length", value: "20cm" }],
});

const mockGetItemSend = mock(async (req: GetItemCommand) => {
  if (req.input.Key!.id.S! === testWidget.id) {
    return {
      Item: {
        id: { S: testWidget.id },
        owner: { S: testWidget.owner },
        label: { S: testWidget.label },
        description: { S: testWidget.description },
        length: { S: "20cm" },
      },
    };
  }
  return {};
});

const expectMockPutItem = (field: string, value: string) =>
  mock(async (req: PutItemCommand) => {
    if (req.input.Item![field].S === value) {
      return { Attributes: true };
    }
    throw new Error("invalid field");
  });

const mockDeleteItemSuccessful = mock(async (req: DeleteItemCommand) => {
  if (req.input!.Key!.id.S === testWidget.id) {
    return { $metadata: true };
  }
});

test("when retrieve dynamo dao item then inflates and returns retrieved item", async () => {
  const mockClient = { send: mockGetItemSend };
  const logger = new VoidLogger();
  const dao = new DynamoWidgetDAO(
    testTable,
    mockClient as unknown as DynamoDBClient,
    logger,
  );

  const resp = await dao.retrieve(testWidget);
  expect(resp).toEqual(testWidget);
});

test("when retrieve dynamo dao item not exist then returns undefined", async () => {
  const mockClient = { send: mockGetItemSend };
  const logger = new VoidLogger();
  const dao = new DynamoWidgetDAO(
    testTable,
    mockClient as unknown as DynamoDBClient,
    logger,
  );

  const resp = await dao.retrieve({
    id: "this-widget-doesnt-exist",
    owner: "simponic",
  });

  expect(resp).toBeUndefined();
});

test("when dynamo dao save then inflates object and returns", async () => {
  const mockClient = {
    send: expectMockPutItem("new_attribute", "exists"),
  };
  const logger = new VoidLogger();
  const dao = new DynamoWidgetDAO(
    testTable,
    mockClient as unknown as DynamoDBClient,
    logger,
  );

  const newWidget = Widget.parse({
    ...testWidget,
    otherAttributes: [...testWidget.otherAttributes!],
  });
  newWidget.otherAttributes!.push({ name: "new_attribute", value: "exists" });

  const resp = await dao.save(newWidget);

  expect(resp).toEqual(newWidget);
});

test("when dynamo dao delete then returns deleted ", async () => {
  const mockClient = {
    send: mockDeleteItemSuccessful,
  };
  const logger = new VoidLogger();

  const dao = new DynamoWidgetDAO(
    testTable,
    mockClient as unknown as DynamoDBClient,
    logger,
  );

  const resp = await dao.delete(testWidget);

  expect(resp).toEqual(testWidget);
});