View Javadoc
1   /**
2    * Copyright (c) 2013-2023, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.github.mock;
31  
32  import com.google.common.base.Optional;
33  import com.jcabi.aspects.Tv;
34  import com.jcabi.github.Event;
35  import java.util.Iterator;
36  import org.hamcrest.MatcherAssert;
37  import org.hamcrest.Matchers;
38  import org.junit.Test;
39  
40  /**
41   * Test case for {@link MkIssueEvents}.
42   * @author Chris Rebert (github@chrisrebert.com)
43   * @version $Id: f8b453ae08480a2fc14c1621adecc58a16a60d42 $
44   * @since 0.23
45   */
46  public final class MkIssueEventsTest {
47      /**
48       * Absent optional string.
49       */
50      private static final Optional<String> ABSENT_STR = Optional.absent();
51  
52      /**
53       * MkIssueEvents can create issue events.
54       * @throws Exception If some problem inside
55       */
56      @Test
57      public void createsIssueEvent() throws Exception {
58          final MkIssueEvents events = this.issueEvents();
59          final String login = "jack";
60          final String type = "locked";
61          final long before = MkIssueEventsTest.now();
62          final Event.Smart event = new Event.Smart(
63              events.create(
64                  type,
65                  2,
66                  login,
67                  MkIssueEventsTest.ABSENT_STR
68              )
69          );
70          final long after = MkIssueEventsTest.now();
71          MatcherAssert.assertThat(
72              event.type(),
73              Matchers.equalTo(type)
74          );
75          MatcherAssert.assertThat(
76              event.author().login(),
77              Matchers.equalTo(login)
78          );
79          MatcherAssert.assertThat(
80              event.url().toString(),
81              Matchers.equalTo(
82                  String.format(
83                      // @checkstyle LineLength (1 line)
84                      "https://api.jcabi-github.invalid/repos/jeff/%s/issues/events/1",
85                      events.repo().coordinates().repo()
86                  )
87              )
88          );
89          MatcherAssert.assertThat(
90              event.createdAt().getTime(),
91              Matchers.greaterThanOrEqualTo(before)
92          );
93          MatcherAssert.assertThat(
94              event.createdAt().getTime(),
95              Matchers.lessThanOrEqualTo(after)
96          );
97      }
98  
99      /**
100      * MkIssueEvents can create an issue event with a label attribute.
101      * @throws Exception If some problem inside
102      */
103     @Test
104     public void createsIssueEventWithLabel() throws Exception {
105         final MkIssueEvents events = this.issueEvents();
106         final String label = "my label";
107         final Event.Smart event = new Event.Smart(
108             events.create(
109                 "labeled",
110                 2,
111                 "samuel",
112                 Optional.of(label)
113             )
114         );
115         MatcherAssert.assertThat(
116             event.label().get().name(),
117             Matchers.equalTo(label)
118         );
119     }
120 
121     /**
122      * MkIssueEvents can get a single issue event.
123      * @throws Exception If some problem inside
124      */
125     @Test
126     public void getsIssueEvent() throws Exception {
127         final MkIssueEvents events = this.issueEvents();
128         final String type = "unlocked";
129         final String login = "jill";
130         final int eventnum = events.create(
131             type,
132             2,
133             login,
134             MkIssueEventsTest.ABSENT_STR
135         ).number();
136         final Event.Smart event = new Event.Smart(events.get(eventnum));
137         MatcherAssert.assertThat(
138             event.number(),
139             Matchers.equalTo(eventnum)
140         );
141         MatcherAssert.assertThat(
142             event.type(),
143             Matchers.equalTo(type)
144         );
145         MatcherAssert.assertThat(
146             event.author().login(),
147             Matchers.equalTo(login)
148         );
149     }
150 
151     /**
152      * MkIssueEvents can iterate over issue events in correct order.
153      * @throws Exception If some problem inside
154      */
155     @Test
156     public void iteratesIssueEvents() throws Exception {
157         final MkIssueEvents events = this.issueEvents();
158         final Event first = events.create(
159             "closed",
160             3,
161             "john",
162             MkIssueEventsTest.ABSENT_STR
163         );
164         final Event second = events.create(
165             "reopened",
166             3,
167             "jane",
168             MkIssueEventsTest.ABSENT_STR
169         );
170         MatcherAssert.assertThat(
171             events.iterate(),
172             Matchers.<Event>iterableWithSize(2)
173         );
174         final Iterator<Event> iter = events.iterate().iterator();
175         MatcherAssert.assertThat(
176             iter.next(),
177             Matchers.equalTo(first)
178         );
179         MatcherAssert.assertThat(
180             iter.next(),
181             Matchers.equalTo(second)
182         );
183     }
184 
185     /**
186      * Create an MkIssueEvents to work with.
187      * Can't use normal IssueEvents because we need the mock-only
188      * {@link MkIssueEvents#create(String, int, String, Optional)} method.
189      * @return MkIssueEvents
190      * @throws Exception If some problem inside
191      */
192     private MkIssueEvents issueEvents() throws Exception {
193         return MkIssueEvents.class.cast(
194             new MkGithub().randomRepo().issueEvents()
195         );
196     }
197 
198     /**
199      * Obtains the current time.
200      * @return Current time (in milliseconds since epoch) truncated to the nearest second
201      */
202     private static long now() {
203         final long sinceepoch = System.currentTimeMillis();
204         return sinceepoch - sinceepoch % Tv.THOUSAND;
205     }
206 }